将以下代码保存为.h文件,在待检测的应用中调用它。
/*****************************************************************
为了使用内存检测,需要在待检测代码中进行以下三步:
1. Define _DEBUG #define _DEBUG
2. Include "crtdbg.h" #include "crtdbg.h"
3. Let your first line in the code be: _CrtSetDbgFlag (ON);
********************************************************************/
#ifndef _CRTDBG_HEADER
#define _CRTDBG_HEADER
#ifdef _DEBUG
extern "C" void WINAPIV NKDbgPrintfW(LPCWSTR lpszFmt, ...);
struct CrtFileName
{
unsigned short* _pusCrtName;
CrtFileName* _pCrtNext;
};
struct _CrtMem
{
CrtFileName* _pCrtFileName;
int _iCrtLine;
unsigned int _uiCrtMemLen;
void* _pCrtMemAddr;
_CrtMem* _pCrtNext;
};
void* operator new(unsigned int s,unsigned short* name,int line);
inline void* __cdecl operator new(unsigned int s)
{ return ::operator new(s, _T(__FILE__), __LINE__); }
void __cdecl operator delete(void *pvMem);
class garbageCollector
{
public:
garbageCollector () {}
~garbageCollector ();
};
#define _CrtSetDbgFlag(ignore) garbageCollector gb;
_CrtMem* _pCrtMemRoot = 0;
CrtFileName* _pCrtFileNameRoot = 0;
void* operator new(unsigned int s,unsigned short* name,int line)
{
void* retPtr = malloc (s);
if (retPtr)
{ _CrtMem* _crtMemCell = (struct _CrtMem*)malloc (sizeof(_CrtMem));
_crtMemCell->_iCrtLine = line;
_crtMemCell->_uiCrtMemLen = s;
_crtMemCell->_pCrtMemAddr = retPtr;
_crtMemCell->_pCrtNext = 0; CrtFileName* _tmpCrtFileName;
for (_tmpCrtFileName = _pCrtFileNameRoot;
_tmpCrtFileName && wcscmp(name, _tmpCrtFileName->_pusCrtName);
_tmpCrtFileName = _tmpCrtFileName->_pCrtNext) {}
if (!_tmpCrtFileName)
{ unsigned short* _crtName = (unsigned short*)malloc ((wcslen (name) + 1) * sizeof(unsigned short));
wcscpy (_crtName, name); CrtFileName* _crtFileName = (struct CrtFileName*)malloc (sizeof (CrtFileName));
_crtFileName->_pusCrtName = _crtName;
_crtFileName->_pCrtNext = 0; if (!_pCrtFileNameRoot) _pCrtFileNameRoot = _crtFileName;
else { for (_tmpCrtFileName = _pCrtFileNameRoot;
_tmpCrtFileName->_pCrtNext;
_tmpCrtFileName = _tmpCrtFileName->_pCrtNext);
_tmpCrtFileName->_pCrtNext = _crtFileName;
}
_tmpCrtFileName = _crtFileName;
}
_crtMemCell->_pCrtFileName = _tmpCrtFileName;
if (!_pCrtMemRoot) { _pCrtMemRoot = _crtMemCell; }
else { _CrtMem* _tmpMemPtr; for (_tmpMemPtr = _pCrtMemRoot; _tmpMemPtr->_pCrtNext; _tmpMemPtr = _tmpMemPtr->_pCrtNext); _tmpMemPtr->_pCrtNext = _crtMemCell;
}
}
return retPtr;
}
void __cdecl operator delete(void *pvMem)
{ if (pvMem)
{ _CrtMem* _tmpMem;
if (pvMem == _pCrtMemRoot->_pCrtMemAddr)
{ _tmpMem = _pCrtMemRoot; _pCrtMemRoot = _pCrtMemRoot->_pCrtNext; free (_tmpMem);
}
else
{ for (_tmpMem = _pCrtMemRoot; _tmpMem->_pCrtNext && (_tmpMem->_pCrtNext->_pCrtMemAddr != pvMem);
_tmpMem = _tmpMem->_pCrtNext);
if (_tmpMem->_pCrtNext)
{ _CrtMem* _tmpMem2;
_tmpMem2 = _tmpMem->_pCrtNext;
_tmpMem->_pCrtNext = _tmpMem2->_pCrtNext;
free (_tmpMem2); }
else
NKDbgPrintfW (_T("%s(%i) : Warning : deletes memory pointer not allocated with new!/n"), _T(__FILE__), __LINE__);
}
free (pvMem);
}
}
garbageCollector::~garbageCollector ()
{ if (!_pCrtMemRoot) NKDbgPrintfW (_T("No memory leaks detected!/n"));
else { _CrtMem* _tmpMem; NKDbgPrintfW (_T("Detected memory leaks!/nDumping objects ->/n"));
for (_tmpMem = _pCrtMemRoot; _tmpMem; _tmpMem = _tmpMem->_pCrtNext)
{
NKDbgPrintfW (_T("%s(%i) : normal block at 0x%08X, %i bytes long/n Data <"), _tmpMem->_pCrtFileName->_pusCrtName, _tmpMem->_iCrtLine, _tmpMem->_pCrtMemAddr, _tmpMem->_uiCrtMemLen);
for (unsigned int i = 0; i < _tmpMem->_uiCrtMemLen; i++)
NKDbgPrintfW (_T("%c"), *(((char*)_tmpMem->_pCrtMemAddr)+i)); NKDbgPrintfW (_T(">/n"));
}
}
CrtFileName* _tmpName = _pCrtFileNameRoot;
for (;_tmpName;)
{ _pCrtFileNameRoot = _tmpName->_pCrtNext; free(_tmpName->_pusCrtName); free(_tmpName); _tmpName = _pCrtFileNameRoot;
}
} #else
#define _CrtSetDbgFlag(ignore) #endif //DEBUG #endif //HEADER