自己写的c++内存泄露检测小工具

本文介绍了一种通过重载全局new和delete操作符来记录内存分配与释放情况的方法,以此实现内存泄漏检测。该工具支持多线程,并可在不同平台上应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   最近在写一个后台服务,代码 量稍微大了些,运行时发现有内存泄露的迹象,裸看代码找到一些但是还是没彻底解决。

据说微软有自带的内存检测工具,我用的是 纯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();

}

#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;
#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();
}
MemGuard.h
#ifndef __MEM_GUARD_
#define __MEM_GUARD_
#include <iostream>
#include <stdio.h>
void * operator new(size_t size,const char * file,int line);
void * operator new[](size_t size,const char * file,int line);
void  operator delete(void * p);
void  operator delete[](void *p);
void memExeTraceInit();
void memDllTraceInit();
void memDllProcessDetach();
#define new new(__FILE__,__LINE__)
#endifv
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值