在使用MFC库开发程序时,我非常喜欢MFC框架中的内存泄漏诊断机制,它的确能很好地帮助我们查找出内存泄漏。可是链接了MFC库也使得生成的可执行文件大了许多,这个没什么负面影响。最可怕的是如果仅为了使用内存诊断机制,而带来了链接库冲突的麻烦。我也是在遇到这个问题时,才写出了一个简易的内存诊断机制。
在windows的SDK中有一套用于诊断内存泄漏的机制,只是MFC封装得更好,所以知名度不够高。下面我封装了CRT中的内存泄漏诊断机制,用起来也比较方便,直接在stdafx.h中包含MyDebug.h, 在要用诊断机制的文件中加入如下的代码。
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
/**//*
* @File: DebugNew.h
*
* @Author: Robert xiao
*
* @Created: 2012/11/04
*
* @Purpose:
*/
#pragma once
#define THIS_FILE __FILE__
void* __cdecl operator new(size_t nSize, int nType, const char* lpszFileName, int nLine);
#ifdef _DEBUG
void* _cdecl operator new(size_t nSize, const char* lpszFileName, int nLine);
void* __cdecl operator new[](size_t nSize, const char* lpszFileName, int nLine);
void __cdecl operator delete(void* p);
void __cdecl operator delete[](void* p);
#define DEBUG_NEW new(THIS_FILE, __LINE__)
#else
#define DEBUG_NEW new
#endif // _DEBUG
/**//*
* @File: DebugNew.cpp
*
* @Author: Robert xiao
*
* @Created: 2012/11/04
*
* @Purpose:
*
*/
#include "stdafx.h"
#include <crtdbg.h>
#include "MyDebug.h"
namespace
{
class AutoDetectMemory
{
public:
AutoDetectMemory()
{
#ifdef _DEBUG
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
}
};
static AutoDetectMemory gs_am;
}
void* _cdecl operator new(size_t nSize, const char* lpszFileName, int nLine)
{
return ::operator new(nSize, _NORMAL_BLOCK, lpszFileName, nLine);
}
void* __cdecl operator new[](size_t nSize, const char* lpszFileName, int nLine)
{
return ::operator new(nSize, _NORMAL_BLOCK, lpszFileName, nLine);
}
void __cdecl operator delete(void* p)
{
#if defined(_DEBUG)
_free_dbg(p, _NORMAL_BLOCK);
#else
free(p);
#endif
}
void __cdecl operator delete[](void* p)
{
::operator delete(p);
}
void* __cdecl operator new(size_t nSize, int nType, const char* lpszFileName, int nLine)
{
#ifndef _DEBUG
UNREFERENCED_PARAMETER(nType);
UNREFERENCED_PARAMETER(lpszFileName);
UNREFERENCED_PARAMETER(nLine);
return ::operator new(nSize);
#else
return _malloc_dbg(nSize, nType, lpszFileName, nLine);
#endif
}