首页 技术 正文
技术 2022年11月16日
0 收藏 462 点赞 3,796 浏览 2581 个字

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

这里介绍两种方法,互为补充,第一种是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可以检查程序整个运行过程中的内存分配情况,也可以将内存泄漏的位置显示出来,如图所示。

Windows平台上C++开发内存泄漏检查方法

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

—————————————————————————–

//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;

}

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,088
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,565
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,413
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,186
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,822
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,905