zoukankan      html  css  js  c++  java
  • 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 est est.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<<" Memory Leaked : ";

                          m_msDiff.DumpStatistics();

                          afxDump<<"Dump Complete ! ";

                   }

           #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:programschatchatdlg.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

  • 相关阅读:
    窗口总在最前的时候信息框弹出解决
    IP地址与子网掩码知识
    六类线、五类线、超五类线有什么区别?
    如何删除internet网关连接图标
    密码输入框用“●”做遮盖符
    万象2004数据库说明
    客户机绑定路由例子bat
    命令行下导入、导出注册表
    网管维护常用命令
    hadoop shell 操作命令
  • 原文地址:https://www.cnblogs.com/candl/p/3848345.html
Copyright © 2011-2022 走看看