C++检查内存泄露

说明,我使用的ide是vs2008



1. 工程设置为debug

内存泄露的检测一般在debug模式下进行


2.在需要检查内存泄露的cpp头部加上

[cpp]  view plain copy
  1. #ifdef  _DEBUG  
  2.  #define _CRTDBG_MAP_ALLOC  
  3.  #include <stdlib.h>  
  4.  #include <crtdbg.h>  
  5.     #define new   new(_NORMAL_BLOCK, __FILE__, __LINE__)  
  6.  #endif  

3.代码中插入这么一句话

EnableMemLeakCheck();

[cpp]  view plain copy
  1. inline void EnableMemLeakCheck()  
  2.  {  
  3.     _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);  
  4.  }  
  5.    

4.然后就可以在输出中看泄露情况了

举个例子,例子中我用newEx表示的上述宏定义中的new

[cpp]  view plain copy
  1. int _tmain(int argc, _TCHAR* argv[])  
  2.  {  
  3.     EnableMemLeakCheck();  
  4.     int num = 10;  
  5.     byte **p = newEx byte *[num];  
  6.     for (int i = 0; i < num; i ++)  
  7.     {  
  8.         Sleep(1);  
  9.         *p = newEx byte[i];  
  10.     }  
  11.    
  12.     long *pl = newEx long[100];  
  13.    
  14.     while(1)  
  15.     {  
  16.         Sleep(100);  
  17.     }  
  18.     return 0;  
  19.  }  

输出中显示的内容(debug下运行程序,然后点叉叉关闭程序)

memory leaks!
 Dumping objects ->
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(101) : {124} normal block at 0x00295CB8, 400 bytes long.
  Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {122} normal block at 0x00294C30, 9 bytes long.
  Data: <         > CD CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {121} normal block at 0x00294BE8, 8 bytes long.
  Data: <        > CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {120} normal block at 0x00299F88, 7 bytes long.
  Data: <       > CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {119} normal block at 0x00299F40, 6 bytes long.
  Data: <      > CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {118} normal block at 0x00299EF8, 5 bytes long.
  Data: <     > CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {117} normal block at 0x00299EB8, 4 bytes long.
  Data: <    > CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {116} normal block at 0x00299E78, 3 bytes long.
  Data: <   > CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {115} normal block at 0x00299E38, 2 bytes long.
  Data: <  > CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {114} normal block at 0x00299DF8, 1 bytes long.
  Data: < > CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {113} normal block at 0x00299DB8, 0 bytes long.
  Data: <> 励p
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(88) : {112} normal block at 0x00299D50, 40 bytes long.
  Data: <0L)             > 30 4C 29 00 CD CD CD CD CD CD CD CD CD CD CD CD 
 Object dump complete.


有文件名和行号,先申请的后释放。


扩展:

实际上是使用了另外的new,在dbgnew.cpp中,列一个例子说明:


[cpp]  view plain copy
  1. void *__CRTDECL operator new[](  
  2.          size_t cb,  
  3.          int nBlockUse,  
  4.          const char * szFileName,  
  5.          int nLine  
  6.          )  
  7.          _THROW1(_STD bad_alloc)  
  8.  {  
  9.      void *res = operator new(cb, nBlockUse, szFileName, nLine );  
  10.    
  11.      RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));  
  12.    
  13.      return res;  
  14.  }  
  15.    


注意,const char *szFileName可以使用__file__也可以使用自定义的类,经过重载为char*(感谢老马提供代码)

例如:

[cpp]  view plain copy
  1. char new_index_recorder_file_name[1024 * 1024][256];  
  2.    
  3.    
  4.    
  5.  class new_index_recorder{  
  6.    
  7.  public:  
  8.    
  9.     new_index_recorder(char* file, int line) : file(file), line(line){  
  10.    
  11.    
  12.    
  13.     }   
  14.    
  15.     operator char*(){  
  16.    
  17.         static unsigned int index;  
  18.    
  19.         sprintf(new_index_recorder_file_name[index], "%s(%d) : %d ", file, line, index++);  
  20.    
  21.         return  new_index_recorder_file_name[index];  
  22.    
  23.     }  
  24.    
  25.  private:  
  26.    
  27.     char* file;  
  28.    
  29.     int line;   
  30.    
  31.  };  


当然,也可以用函数来返回char*指针

[cpp]  view plain copy
  1. int g_count = 0;  
  2.    
  3.  class OperNew  
  4.  {  
  5.  public:  
  6.     OperNew()  
  7.     {     
  8.         g_count ++;  
  9.         pC = new char[20];  
  10.         memset(pC, 0, 10);  
  11.         sprintf(pC, "No.%d", g_count);  
  12.     }  
  13.     char* GetChar()  
  14.     {  
  15.         return pC;  
  16.     }  
  17.  private:  
  18.     char * pC ;  
  19.  };  

这样就能返回自定义的内容了。本次的返回加上了一个构造时候的序号,当然也可以添加时间等。结果如下:

e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(95) : 11 (95) : {123} normal block at 0x002B4C78, 400 bytes long.
  Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 10 (92) : {122} normal block at 0x002B4C30, 9 bytes long.
  Data: <         > CD CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 9 (92) : {121} normal block at 0x002B4BE8, 8 bytes long.
  Data: <        > CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 8 (92) : {120} normal block at 0x002B9F88, 7 bytes long.
  Data: <       > CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 7 (92) : {119} normal block at 0x002B9F40, 6 bytes long.
  Data: <      > CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 6 (92) : {118} normal block at 0x002B9EF8, 5 bytes long.
  Data: <     > CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 5 (92) : {117} normal block at 0x002B9EB8, 4 bytes long.
  Data: <    > CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 4 (92) : {116} normal block at 0x002B9E78, 3 bytes long.
  Data: <   > CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 3 (92) : {115} normal block at 0x002B9E38, 2 bytes long.
  Data: <  > CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 2 (92) : {114} normal block at 0x002B9DF8, 1 bytes long.
  Data: < > CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 1 (92) : {113} normal block at 0x002B9DB8, 0 bytes long.
  Data: <> h鴌
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(88) : 0 (88) : {112} normal block at 0x002B9D50, 40 bytes long.
  Data: <0L+             > 30 4C 2B 00 CD CD CD CD CD CD CD CD CD CD CD CD 
 Object dump complete.
 程序“[8796] test_MEM_LEAK.exe: 本机”已退出,返回值为 -1073741510 (0xc000013a)。


小提示:

将输出文件拷贝到UE中,然后查找泄露行号出现的次数,可以计算出泄露的数目。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值