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.
开发工具:VS2005。(在VC++6.0中好像也可以这么用)
目的:检测C++代码中有无内存泄漏(即动态分配了内存,而没有正确释放)。
操作步骤:
一、把以下debug_new.h和debug_new.cpp文件加入项目中。
debug_new.h
- #ifndef _DEBUG_NEW_H_
 - #define _DEBUG_NEW_H_
 - #ifdef _DEBUG
 - #undef new
 - extern void _RegDebugNew( void );
 - extern void* __cdecl operator new( size_t, const char*, int );
 - extern void __cdecl operator delete( void*, const char*, int);
 - #define new new(__FILE__, __LINE__)
 - #define REG_DEBUG_NEW _RegDebugNew();
 - #else
 - #define REG_DEBUG_NEW
 - #endif // _DEBUG
 - #endif // _DEBUG_NEW_H_
 
debug_new.cpp
- //#include "debug_new.h"
 - #ifdef _DEBUG
 - #include
 - #include
 - class _CriSec
 - {
 - CRITICAL_SECTION criSection;
 - public:
 - _CriSec() { InitializeCriticalSection( &criSection ); }
 - ~_CriSec() { DeleteCriticalSection( &criSection ); }
 - void Enter() { EnterCriticalSection( &criSection ); }
 - void Leave() { LeaveCriticalSection( &criSection ); }
 - } _cs;
 - void _RegDebugNew( void )
 - {
 - _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF );
 - }
 - void* __cdecl operator new( size_t nSize, const char* lpszFileName, int nLine )
 - {
 - // comment 1: MFC中提供的debug new虽然加了锁,但我在实际测试的时候发现多线程并发
 - // 调用的时候还是抛出了系统错误,所以我在这里加了一个线程互斥量.
 - // comment 2: debug new和debug delete之间需不需要互斥我并不知道,保险起见,我同样
 - // 加了线程互斥量.
 - // comment 3: 按照C++标准规定,在operator new失败后应当调用set_new_handler设置的
 - // 函数,但是MSDN中却说"头文件new中的set_new_handler是stub的,而应该使
 - // 用头文件new.h中的_set_new_handler",这简直是滑天下之大稽.
 - // 以下是VC++6.0中的set_new_handler定义:
 - // new_handler __cdecl set_new_handler( new_handler new_p )
 - // {
 - // assert( new_p == 0 ); // cannot use stub to register a new handler
 - // _set_new_handler( 0 );
 - // return 0;
 - // }
 - // 所以我也无计可施,只能舍弃set_new_handler的作用.
 - _cs.Enter();
 - void* p = _malloc_dbg( nSize, _NORMAL_BLOCK, lpszFileName, nLine );
 - _cs.Leave();
 - return p;
 - }
 - void __cdecl operator delete( void* p, const char* , int )
 - {
 - _cs.Enter();
 - _free_dbg( p, _CLIENT_BLOCK );
 - _cs.Leave();
 - }
 - #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
- #include
 - #include
 - #include "debug_new.h" // +
 - #define _CRTDBG_MAP_ALLOC
 - #include
 - #include
 - using namespace std;
 - int main()
 - {
 - REG_DEBUG_NEW; // +
 - char* name = new char[2];
 - name[0] = 'A';
 - name[1] = 'B';
 - //delete name;
 - _CrtDumpMemoryLeaks();
 - cout << "--End--" << endl;
 - return 0;
 - }
 
三、按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
                    
                
                
            
        
浙公网安备 33010602011771号