使用CRT定位内存泄漏

1. 使能内存泄漏检测
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
注1:语句顺序不能修改;
注2:仅对DEBUG版本有效
注3:#define语句可以去掉,但leak dump会丢失细节信息,如:泄漏的代码文件及行号

2. 打印泄漏内存报告
在合适的地方调用下面的语句,即可看到内存泄漏报告:
_CrtDumpMemoryLeaks();

3. 如果应用程序有多个出口,可 以通过设置调试标志自动在程序退出时打印内存泄漏信息,而不是手动在每个出口添加:
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

4. 默认情 况下报告打印在VS的Debug面板的Output窗口,该行为可以通过下面的API进行修改:
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );


CRT内存泄漏报告解读。。

如果定义了_CRTDBG_MAP_ALLOC宏,报告会是这样:
Detected memory leaks!
Dumping objects ->
C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18}
normal block at 0x00780E80, 64 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

如果没有定义,则是这样:
Detected memory leaks!
Dumping objects ->
{18} normal block at 0x00780E80, 64 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

解读:
内存块号,这里是18;
内存块类型:这里是normal;
泄漏的内存地址:这里是0x00780E80;
泄漏的内存块大小,这里是64bytes;
泄漏内存的前16byte的十六进制值;

CRT内存类型有5种:
normal:应用程序自己开辟的内存块
client:MFC对象特有的类型
crt:crt自己使用的内存块
free:已经被释放的(不会出现在报告中)
ignore:应用程序显示标志为排除在内存泄漏报告中的内存块


CRT通过改写new和malloc来实现内存泄漏监视:
#ifdef _DEBUG
   #ifndef DBG_NEW
      #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
      #define new DBG_NEW
   #endif
#endif  // _DEBUG


设置内存开辟断点:
1.在监视窗口修改crt全局变量:_crtBreakAlloc,
如果使用/MD编译选项,需加上上下文操作符: {,,ucrtbased.dll}_crtBreakAlloc,如果使用/MD编译选项,需加上上下文操作符:
2. 通过CRT API设置 _CrtSetBreakAlloc(xx);


手动比较内存:
典型用法:
_CrtMemState s1;
_CrtMemCheckpoint( &s1 );
// memory allocations take place here
_CrtMemState s2;
_CrtMemCheckpoint( &s2 );

_CrtMemState s3;
if ( _CrtMemDifference( &s3, &s1, &s2) )
   _CrtMemDumpStatistics( &s3 );
   
  

posted @ 2015-11-07 16:42  Through  阅读(1301)  评论(0编辑  收藏  举报