C++经验之检测内存泄露

来源:互联网 发布:四川大学网络教育吧 编辑:程序博客网 时间:2024/05/27 20:51

     C++具有动态分配和释放内存的能力,所谓成也萧何败萧何,这种能力如果使用疏忽会造成内存泄露。本文简单介绍2种检测内存泄露的方法。

【使用调试器和CRT库】

在程序的开头包含如下说明。在VS2010平台上,如果要显示泄露的内存原先分配的地方,需要包括下面第二段(在VS2008上就不用),在调试模式下开启new的内存分配跟踪,显示文件和行号。

#include "stdafx.h"#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>#ifdef _DEBUG#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)#endifint _tmain(int argc, _TCHAR* argv[]){return 0;}


 在需要检测内存泄露的地方,包含_CrtDumpMemoryLeaks()。

int _tmain(int argc, _TCHAR* argv[]){int* pi = new int;char* name = new char[4];name[0] = 'L';name[1] = 'i';name[2] = 'l';name[3] = 'y';_CrtDumpMemoryLeaks();delete pi;return 0;}


注意_CrtDumpMemoryLeaks只是显示当前的内存泄露,即它执行时,所有未销毁的对象均会被报告出来,所以应该尽量在程序的最后执行。上文中虽然指针 pi 被正确释放了,但是在_CrtDumpMemoryLeaks之后,所以output窗口的输出仍然会报告 pi 的泄露情况。

双击报告文件行号的那行,可以跳转到code中的相应位置。

{118}:第118次内存分配操作发生了泄露。在初始化过程中肯定已经分配过很多了,所以上文第一次分配是117次,第二次是118次。

block:内存的类型,本文都是normal block。常用的有三种:

-normal (普通):程序分配的内存。

-client (客户端):专门用于MFC程序中需要析构函数的对象。MFC new操作符根据具体情况,为所创建的对象建立普通块或者客户块。

-CRT(运行时):由C Runtime Library 供自己使用而分配的内存块,有CRT 库自己来管理。

0x00348998:以16进制表示的内存位置

4 bytes:以字节表示的内存块的大小。

Data:内存块中前16个字节的内容。

 

如果程序有多个出口,或者不确定在哪儿会退出,可以在程序的开头包含以下语句,那么无论程序在哪里退出,都会自动调用_CrtDumpMemoryLeaks

_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

由于 pi 指针已经被成功释放了,所以这次报告的泄露只有name。

【使用工具】

我使用的工具叫做:BoundsChecker 7。仍以上文的代码为例,编译生成MemoryLeakTest.exe。

#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){int* pi = new int;char* name = new char[4];name[0] = 'L';name[1] = 'i';name[2] = 'l';name[3] = 'y';return 0;}


P.S. 得把刚才“使用调试器和CRT库”加的相关代码都去掉,不然检测不出来,不知道为啥。。

在BC中打开exe文件,Program -> Settings中可以设置命令行参数。“General”页面中,可以勾上“Show memory and resource viewer when application exits”,在“Memory Tracking”页面,也有相关设置。

 

执行完毕出现“BoundsChecker Memory and Resource Viewer”。列举出了内存泄露的具体信息。

 

其他工具还有(都没用过)等。

Visual Leak Detector:http://apps.hi.baidu.com/share/detail/1927208

puriify

 

【参考】

http://blog.csdn.net/rye_grass/article/details/1551985

原创粉丝点击