充分的利用调试工具可以非常方便地避免内存泄漏问题。

这里介绍两种方法,互为补充,第一种是VC编译器提供的方法,第二种是专用的内存泄漏检查工具Memmory Validator。这两种方法的基本原理是一样的:内存分配要通过CRT在运行时实现,只要在分配内存和释放内存时分别做好记录,程序结束时对比分配内存和释放内存的记录就可以确定是不是有内存泄漏。其中,第一种方法重载了new操作符,第二种方法是替换了CRT运行时库,在用户程序与运行库之间加了一层,用于记录内存分配情况。两种方法的不同是前者是在编译时完成的,分析内存情况的代码编译到执行文件中,用于程序的debug版本,后一种对编译过程没有影响,在执行过程中截留与CRT的交互信息。

第一种方法是MSDN中介绍了,在需要检查内存分配情况的cpp文件中引用<stdlib.h>和<ctrdbg.h>两个头文件,放于最头部,再用宏代换的方法用重载后的new操作符代替原来的new操作符,如下列代码所示,在程序退出的位置调用_CrtDumpMemoryLeaks()输出全部没有释放的内存内容,及申请这些内存的源代码位置,非常便于调试。

但这种方法有缺陷,_CrtDumpMemoryLeaks()必须在main()函数结束之前调用,所以main()函数中的栈对象还没有析构,会被当做内存泄漏,如下面代码中的NewClass类的对象,实际是没有问题的。另外就是不同编译器实现非ASCII码字符时可能会有所不同,如下面代码中的汉字串都被视为内存泄漏。

#include <stdlib.h>

#include <crtdbg.h>

#include <string>

#include <iostream>

#include <vector>

using namespace std;

#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)

#define new DEBUG_NEW

struct AlertDescriptionString

{

unsigned int ID;

string Name;

string Desp;

};

const AlertDescriptionString String[] =

{

{0,"AAA","BBBB"},

// memory leak count by _CRTDBG_MAP_ALLOC

{1,"CCC","__XXX__检测到可能由AirJack发出的数据包"}

};

struct AlertDescriptionStr

{

unsigned int ID;

char* Name;

char* Desp;

};

const AlertDescriptionStr Str[] =

{

{0,"AAA","BBBB"},

{1,"CCC","检测到可能由AirJack发出的数据包"}

};

void leak_memory(void)

{

vector<unsigned int *> vec;

for( int j = 0; j < 2; j++)

{

vec.push_back(new unsigned int(0));

}

}

class NewClass

{

void * p ;

public:

NewClass()

{

p = (void*) new char[10];

}

~NewClass()

{

delete [] p;

}

};

int * p = new int(9);

int real_main_fun (int argc, char ** argv)

{

leak_memory();

return 0;

}

int main (int argc, char ** argv)

{

string str("__YYY__检测到可能由AirJack发出的数据包");

NewClass cls;

int i = real_main_fun(argc, argv); // 原有的main函数体

if(_CrtDumpMemoryLeaks())

cout<< " memory leak " << endl;

return i;

}

第二种方法正好是它的补充,Memmory Validator可以检查程序整个运行过程中的内存分配情况,也可以将内存泄漏的位置显示出来,如图所示。

在实际应用第一种方法时,可以采用两个头文件,用于大型工程的调试,几乎不对其他部分代码产生影响。

-----------------------------------------------------------------------------

//config.h

#define MEMORY_DEBUG

#ifdef MEMORY_DEBUG

#include <stdlib.h>

#include <crtdbg.h>

#endif // MEMORY_DEBUG

------------------------------------------------------------------------------

//debug.h

#ifdef MEMORY_DEBUG

#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)

#define new DEBUG_NEW

#endif // MEMORY_DEBUG

-------------------------------------------------------------------------------

//main.cpp

#include "config.h” // config.h, 第一个头文件

#include "alertparser.h"

#include "alertinfocache.h"

#include <iostream>

#include <pcap.h>

#include "debug.h" //debug.h, 最后一个头文件

int main (int argc, char ** argv)

{

int i = real_main_fun(argc, argv); // 原有的main函数体

if(_CrtDumpMemoryLeaks())

cout<< " memory leak " << endl;

return i;

}

Windows平台上C++开发内存泄漏检查方法的更多相关文章

  1. C++程序在Windows平台上各种定位内存泄漏的方法,并对比了它们的优缺点

    一.前言 在Linux平台上有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器,再加上它的开源属性,相对而言,处理问题容易形成“统一”的标准.而在W ...

  2. c# 内存泄漏检查心得

    系统环境 windows 7 x64 检查工具:ANTS Memory Profiler 7 或者 .NET Memory Profiler 4.0 开发的软件为winform / windows s ...

  3. Windows平台下PHP开发环境的配置

    Windows平台下PHP开发环境的配置 一.基本环境 1.Windows XP 32位 2.Apache 2.2.25,下载地址:http://mirror.bit.edu.cn/apache/ht ...

  4. iOS学习——内存泄漏检查及原因分析

    项目的代码很多,前两天老大突然跟我说项目中某一个ViewController的dealloc()方法没有被调用,存在内存泄漏问题,需要排查原因,解决内存泄漏问题.由于刚加入项目组不久,对出问题的模块的 ...

  5. Windows平台上Caffe的训练与学习方法(以数据库CIFAR-10为例)

    Windows平台上Caffe的训练与学习方法(以数据库CIFAR-10为例) 在完成winodws平台上的caffe环境的搭建之后,亟待掌握的就是如何在caffe中进行训练与学习,下面将进行简单的介 ...

  6. C++程序内存泄漏检测方法

    一.前言 在Linux平台上有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器,再加上它的开源属性,相对而言,处理问题容易形成“统一”的标准.而在W ...

  7. Android内存管理(5)*官方教程:Logcat内存日志各字段含义,查看当前内存快照,跟踪记录内存分配,用adb查看内存情况时各行列的含义,捕获内存快照的3种方法,如何让程序暴漏内存泄漏的方法

    Investigating Your RAM Usage In this document Interpreting Log Messages                 内存分析日志中各消息的含 ...

  8. VS2005内存泄漏检测方法[转载]

    一.非MFC程序可以用以下方法检测内存泄露: 1. 程序开始包含如下定义: #ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __ ...

  9. windows平台下的oracle ORA-01031的解决方法

    今天下午遇到一个很怪异的问题,在windows平台下sqlplus  / as sysdba登陆数据库,提示权限不足, 当时就纳闷了,sys用户登陆数据库还能权限不足,问题出现了,就开始寻找解决方法呗 ...

随机推荐

  1. ubuntu下mysql的环境搭建及使用

    ubuntu下mysql的环境搭建及使用 环境安装 使用如下命令分别安装服务端程序,客户端程序,及客户端依赖库 sudo apt-get install mysql-server sudo apt-g ...

  2. XML中的Xpath解析的例子

    /*XPath 术语节点(Node)在 XPath 中,有七种类型的节点:元素.属性.文本.命名空间.处理指令.注释以及文档(根)节点.XML 文档是被作为节点树来对待的.树的根被称为文档节点或者根节 ...

  3. javascript笔记——jQuery插件开发的几种方式

    jQuery插件开发分为两种: 1 类级别  类级别你可以理解为拓展jquery类,最明显的例子是$.ajax(...),相当于静态方法. 开发扩展其方法时使用$.extend方法,即jQuery.e ...

  4. Js 对象三

    一.screen对象 Width:屏幕的宽度 Height:屏幕的高度 availWidth:屏幕的有效宽度 availhHeight:屏幕的有效高度 (不包含任务栏) colorDepth:色深 二 ...

  5. Gitlab 与 Git Windows 客户端一起使用的入门流程

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3824934.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  6. apache 设置禁止访问某些文件或目录

    [apache配置禁止访问]1. 禁止访问某些文件/目录增加Files选项来控制,比如要不允许访问 .inc 扩展名的文件,保护php类库:<Files ~ "\.inc$" ...

  7. 使用AE进行点的坐标投影变换

    private IPoint PRJtoGCS( double x, double y) { IPoint pPoint = new PointClass(); pPoint.PutCoords(x, ...

  8. PHP、Java、C#实现URI参数签名算法,确保应用与REST服务器之间的安全通信,防止Secret Key盗用、数据篡改等恶意攻击行为

    简介 应用基于HTTP POST或HTTP GET请求发送Open API调用请求时,为了确保应用与REST服务器之间的安全通信,防止Secret Key盗用.数据篡改等恶意攻击行为,REST服务器使 ...

  9. Spark Streaming揭秘 Day28 在集成开发环境中详解Spark Streaming的运行日志内幕

    Spark Streaming揭秘 Day28 在集成开发环境中详解Spark Streaming的运行日志内幕 今天会逐行解析一下SparkStreaming运行的日志,运行的是WordCountO ...

  10. Pandas简易入门(三)

    本节主要介绍一下Pandas的数据结构,本文引用的网址:https://www.dataquest.io/mission/146/pandas-internals-series 本文所使用的数据来自于 ...