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

一、非MFC程序可以用以下方法检测内存泄露:

1. 程序开始包含如下定义:

                #ifdef _DEBUG

                       #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)

               #else

                       #define DEBUG_CLIENTBLOCK

               #endif   // _DEBUG

               #define _CRTDBG_MAP_ALLOC

                #include

              #include

              #ifdef _DEBUG

                      #define new   DEBUG_CLIENTBLOCK

               #endif // _DEBUG

2.程序中添加下面的函数:

            _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);

Debug版本程序运行结束后如有内存泄漏,输出窗口中会显示类似信息:

          Detected memory leaks!

           Dumping objects -> g:\programs\test\test.cpp(16) :

                 {51} client block at 0x00385C58, subtype 0, 4 bytes long.

                 Data: < > CD CD CD CD Object dump complete.

二、MFC程序内存泄漏检测方法:

1. 在 CMyApp 中添加如下三个 CMemoryState 类的成员变量:

          #ifdef _DEBUG

              protected: CMemoryState m_msOld, m_msNew, m_msDiff;

         #endif // _DEBUG

2. 在 CMyApp::InitInstance() 中添加如下代码:

         #ifdef _DEBUG

               m_msOld.Checkpoint();

         #endif // _DEBUG

3.在 CMyApp::ExitInstance() 中添加如下代码:

        #ifdef _DEBUG

               m_msNew.Checkpoint();

               if (m_msDiff.Difference(m_msOld, m_msNew))

               {

                      afxDump<<"\nMemory Leaked :\n";

                      m_msDiff.DumpStatistics();

                      afxDump<<"Dump Complete !\n\n";

               }

       #endif // _DEBUG

        Debug版本程序运行结束后如有内存泄漏,输出窗口中会显示类似信息:

               Memory Leaked :

                      0 bytes in 0 Free Blocks. 8 bytes in 1 Normal Blocks.

                      0 bytes in 0 CRT Blocks. 0 bytes in 0 Ignore Blocks.

                      0 bytes in 0 Client Blocks. Largest number used: 8825 bytes.

                      Total allocations: 47506 bytes.

                      Dump Complete !

               Detected memory leaks!

                      Dumping objects -> g:\programs\chat\chatdlg.cpp(120) :

                     {118} normal block at 0x00D98150, 8 bytes long.

                      Data: < > A8 7F D9 00 01 00 00 00 Object dump complete.

 

 

分类: VC++ 2011-06-04 16:28 810人阅读 评论(1) 收藏 举报

开发工具:VS2005。(在VC++6.0中好像也可以这么用)

目的:检测C++代码中有无内存泄漏(即动态分配了内存,而没有正确释放)。

操作步骤:

一、把以下debug_new.h和debug_new.cpp文件加入项目中。

debug_new.h

  1.   
  2.   
  3.   
  4.   
  5.   
  6.   
  7.   
  8. #ifndef _DEBUG_NEW_H_  
  9. #define _DEBUG_NEW_H_  
  10.   
  11.     #ifdef _DEBUG  
  12.   
  13.         #undef new  
  14.         extern void _RegDebugNew( void );  
  15.         extern void* __cdecl operator new( size_t, const char*, int );  
  16.         extern void __cdecl operator delete( void*, const char*, int);  
  17.         #define new new(__FILE__, __LINE__)  
  18.           
  19.         #define REG_DEBUG_NEW _RegDebugNew();  
  20.   
  21.     #else  
  22.   
  23.         #define REG_DEBUG_NEW  
  24.   
  25.     #endif // _DEBUG  
  26.   
  27. #endif // _DEBUG_NEW_H_  

 

debug_new.cpp

 

 

[c-sharp] view plaincopy
  1.   
  2.   
  3.   
  4.   
  5.   
  6. //#include "debug_new.h"  
  7.  
  8. #ifdef _DEBUG  
  9.  
  10. #include   
  11. #include   
  12.   
  13. class _CriSec  
  14. {  
  15.     CRITICAL_SECTION criSection;  
  16. public:  
  17.     _CriSec()    { InitializeCriticalSection( &criSection ); }  
  18.     ~_CriSec()   { DeleteCriticalSection( &criSection );     }  
  19.     void Enter() { EnterCriticalSection( &criSection );      }  
  20.     void Leave() { LeaveCriticalSection( &criSection );      }  
  21. } _cs;  
  22.   
  23. void _RegDebugNew( void )  
  24. {  
  25.     _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF );  
  26. }  
  27. void* __cdecl operator new( size_t nSize, const char* lpszFileName, int nLine )  
  28. {  
  29.     // comment 1: MFC中提供的debug new虽然加了锁,但我在实际测试的时候发现多线程并发  
  30.     //            调用的时候还是抛出了系统错误,所以我在这里加了一个线程互斥量.  
  31.     // comment 2: debug new和debug delete之间需不需要互斥我并不知道,保险起见,我同样  
  32.     //            加了线程互斥量.  
  33.     // comment 3: 按照C++标准规定,在operator new失败后应当调用set_new_handler设置的  
  34.     //            函数,但是MSDN中却说"头文件new中的set_new_handler是stub的,而应该使  
  35.     //            用头文件new.h中的_set_new_handler",这简直是滑天下之大稽.  
  36.     //            以下是VC++6.0中的set_new_handler定义:  
  37.     //                new_handler __cdecl set_new_handler( new_handler new_p )  
  38.     //                {  
  39.     //                    assert( new_p == 0 ); // cannot use stub to register a new handler  
  40.     //                    _set_new_handler( 0 );  
  41.     //                    return 0;  
  42.     //                }  
  43.     //            所以我也无计可施,只能舍弃set_new_handler的作用.  
  44.   
  45.     _cs.Enter();  
  46.     void* p = _malloc_dbg( nSize, _NORMAL_BLOCK, lpszFileName, nLine );  
  47.     _cs.Leave();  
  48.     return p;  
  49. }  
  50. void __cdecl operator delete( void* p, const char* , int  )  
  51. {  
  52.     _cs.Enter();  
  53.     _free_dbg( p, _CLIENT_BLOCK );  
  54.     _cs.Leave();  
  55. }  
  56.  
  57. #endif  

 

二、在需要检测的DynamicMem.cpp中加入

1.

#include "debug_new.h"。

2.

 使用调试堆函数:


#define _CRTDBG_MAP_ALLOC 
#include 

#include


  注意:#include 语句的顺序。如果更改此顺序,所使用的函数可能无法正确工作。

3.main()中一开始处加入REG_DEBUG_NEW宏

 

4.在需要检测内存泄漏的地方添加下面这条语句来输出内存泄漏信息:

_CrtDumpMemoryLeaks();


测试实例程序:

DynamicMem.cpp

 

  1. #include  
  2. #include  
  3. #include "debug_new.h" // +  
  4.   
  5. #define _CRTDBG_MAP_ALLOC    
  6. #include    
  7.   
  8. #include   
  9.   
  10. using namespace std;  
  11.   
  12. int main()  
  13. {  
  14.     REG_DEBUG_NEW; // +  
  15.   
  16.     char* name = new char[2];  
  17.     name[0] = 'A';  
  18.     name[1] = 'B';  
  19.       
  20.     //delete name;  
  21.   
  22.   
  23.     _CrtDumpMemoryLeaks();   
  24.   
  25.     cout << "--End--" << endl;  
  26.   
  27.     return 0;  
  28. }     

 

三、按F5运行。

会在“调试”窗口中显示:

Detected memory leaks!
Dumping objects ->
e:/workspaces/c++/dynamicmem/dynamicmem/dynamicmem.cpp(78) : {120} normal block at 0x003B6360, 2 bytes long.
 Data: 41 42
Object dump complete.

 

这说明有内存泄漏。

如里把delete[] name;前去掉注释,则“调试”窗口中就不会出现以上的信息,说明无内存泄漏。

 

以上参考:http://blog.sina.com.cn/s/blog_51396f890102f96e.html

 

posted @ 2014-07-16 11:46  guang_blog  阅读(502)  评论(0编辑  收藏  举报