最近在写一个后台服务,代码 量稍微大了些,运行时发现有内存泄露的迹象,裸看代码找到一些但是还是没彻底解决。
据说微软有自带的内存检测工具,我用的是 纯C++,实验了下不灵,一怒之下自己写了个 检测内存泄露的工具。
原理其实很简单,就是 重载全局的new和delete,记录分配和释放的内存 。用法很简单,如下
.exe/dll工程
1>将.h和.cpp加入工程
2>在别的cpp中加入#include<.h>
3>在main函数中开始处加入函数调用memExeTraceInit();
4>如果在dll中使用,则在dllmain的processAttech时加入memDllTraceInit()调用;
在processDetach时加入logOut()调用。
5>多线程同步安全。
6>跨平台,现在windows下支持多线程安全,linux下不支持多线程安全,简单修改下lock()和unlock()函数就可以实现linux下的多线程安全。
第一次 写技术性 博客,不知道怎么传 附件, 就把代码贴在下边吧。
MemGuard.cpp
#include <iostream>
#include <malloc.h>
#include <map>
#include <string>
#ifdef WIN32
#include <Windows.h>
#else
#include <pthread.h>
#endif
class __fileInfo
{
public:
__fileInfo();
std::string file;
int line;
};
#ifdef WIN32
static HANDLE __hmutex = CreateMutex(NULL,false,NULL);
#else
//定义linux mutex
#endif
void lock()//多线程锁函数
{
#ifdef WIN32
WaitForSingleObject(__hmutex,INFINITE);
#else
//Linux 锁
#endif
}
void unlock()
{
#ifdef WIN32
ReleaseMutex(__hmutex);
#else
//Linux 锁
#endif
}
using namespace std;
static bool __initialized = false;
static map<long,__fileInfo> __memtrace;
__fileInfo::__fileInfo()
{
this->line = -1;
}
void * operator new[](size_t size,const char * file,int line)
{
void * p = NULL;
if (size == 0)
{
size =1;
}
while (1) {
p = malloc(size);
if (p!=NULL)
{
break;
}
// 分配不成功,找出当前出错处理函数
new_handler globalhandler = set_new_handler(0);
set_new_handler(globalhandler);
if (globalhandler) (*globalhandler)();
else throw std::bad_alloc();
}
if (p !=NULL && __initialized == true)
{
__fileInfo info;
lock();
info.file = string(file);
info.line = line;
__memtrace.insert(make_pair((long)p,info));
unlock();
}
return p;
}
void * operator new(size_t size,const char * file,int line)
{
void * p = NULL;
if (size == 0)
{
size =1;
}
while (1) {
p = malloc(size);
if (p!=NULL)
{
break;
}
// 分配不成功,找出当前出错处理函数
new_handler globalhandler = set_new_handler(0);
set_new_handler(globalhandler);
if (globalhandler) (*globalhandler)();
else throw std::bad_alloc();
}
if (p !=NULL && __initialized == true)
{
__fileInfo info;
lock();
info.file = string(file);
info.line = line;
__memtrace.insert(make_pair((long)p,info));
unlock();
}
return p;
}
void operator delete(void * p)
{
if (__initialized == true)
{
lock();
__memtrace.erase(long(p));
unlock();
}
free(p);
}
void operator delete[](void * p)
{
if (__initialized == true)
{
lock();
__memtrace.erase(long(p));
unlock();
}
//free(p);
free(p);
}
void logOut()
{
FILE * fp = fopen("MemGuard.log","w+");
if (fp == NULL)
{
return;
}
fprintf(fp,"MemGuard的输出:/n");
for (map<long,__fileInfo>::iterator iter = __memtrace.begin();iter!= __memtrace.end();iter++)
{
fprintf(fp,"内存泄露:/n");
fprintf(fp," addr: 0x%08X/n",iter->first);
fprintf(fp," file: %s/n",iter->second.file.c_str());
fprintf(fp," line: %d/n",iter->second.line);
}
fclose(fp);
CloseHandle(__hmutex);
return;
}
void memExeTraceInit()
{
atexit(logOut);
__hmutex = CreateMutex(NULL,false,NULL);
__initialized = true;
}
void memDllTraceInit()
{
__hmutex = CreateMutex(NULL,false,NULL);
__initialized = true;
}
void memDllProcessDetach()
{
logOut();
}