直接上代码,一个跟踪内存分配的类,可以检测是否有内存泄露:
头文件
#ifndef MEMCHECK_H
#define MEMCHECK_H
#include<cstddef>
#ifdef _cplusplus
extern "C"{
#endif
void* operator new(std::size_t ,const char* ,long);
void* operator new[](std::size_t ,const char* ,long);
#define new new(__FILE__,__LINE__)
extern bool traceFlag;
#define TRACE_ON() traceFlag =true
#define TRACE_OFF() traceFlag = false
extern bool activeFlag;
#define MEM_ON() activeFlag = true
#define MEM_OFF() activeFlag = false
#ifdef _cplusplus
}
#endif
#endif
cpp文件
#include<cstdio>
#include<cstdlib>
#include<cassert>
#include<cstddef>
using namespace std;
#undef new
bool traceFlag = true;
bool activeFlag = false;
namespace {
struct Info{
void* ptr;
const char* file;
long line;
};
const size_t MAXPTRS=10000u;
Info memMap[MAXPTRS];
size_t nptrs=0;
int findPtr(void* p){
for(size_t i=0;i<nptrs;++i)
if(memMap[i].ptr==p)
return i;
return -1;
}
void delPtr(void* p){
int pos=findPtr(p);
assert(pos>=0);
for(size_t i=pos;i<nptrs-1;++i)
memMap[i]=memMap[i+1];
--nptrs;
}
struct Sentinel{
~Sentinel(){
if(nptrs>0){
printf("Leak memory at:/n");
for(size_t i=0;i<nptrs;i++)
printf("/t%p(file:%s,line %ld)/n",
memMap[i].ptr,memMap[i].file,memMap[i].line);
}
else
printf("No user memory leaks/n");
}
};
Sentinel s;
}//end of anonymous namespace
void*
operator new(size_t siz,const char* file ,long line){
void* p=malloc(siz);
if(activeFlag){
if(nptrs==MAXPTRS){
printf("memory map too small(intcrease MAXPTRS)/n");
exit(1);
}
memMap[nptrs].ptr=p;
memMap[nptrs].file=file;
memMap[nptrs].line=line;
++nptrs;
}
if(traceFlag){
printf("Allocate %u bytes at address %p",siz,p);
printf("(file: %s,line : %ld)/n",file,line);
}
return p;
}
void*
operator new[](size_t siz,const char* file,long line){
return operator new(siz,file,line);
}
void operator delete(void *p){
if(findPtr(p)>=0){
free(p);
assert(nptrs>0);
delPtr(p);
if(traceFlag)
printf("Deleted memory at address %p/n",p);
}
else if(!p && activeFlag)
printf("Attempt to delete unknown pointer:%p/n",p);
}
void operator delete[](void *p){
operator delete(p);
}
生出动态链接库 g++ -shared -fpic libmemcheck.so
调用的时候g++ xx.cpp -L. -lmemcheck
效果很好,有个对比,size一下
text data bss dec hex filename
7664 388 120204 128256 1f500 a.out
text data bss dec hex filename
6176 380 180 6736 1a50 a.out
但是有个问题阿,只能把so文件扔到/usr/lib 下,才可以跑,否则找不到。牛人帮忙阿~!
头文件
#ifndef MEMCHECK_H
#define MEMCHECK_H
#include<cstddef>
#ifdef _cplusplus
extern "C"{
#endif
void* operator new(std::size_t ,const char* ,long);
void* operator new[](std::size_t ,const char* ,long);
#define new new(__FILE__,__LINE__)
extern bool traceFlag;
#define TRACE_ON() traceFlag =true
#define TRACE_OFF() traceFlag = false
extern bool activeFlag;
#define MEM_ON() activeFlag = true
#define MEM_OFF() activeFlag = false
#ifdef _cplusplus
}
#endif
#endif
cpp文件
#include<cstdio>
#include<cstdlib>
#include<cassert>
#include<cstddef>
using namespace std;
#undef new
bool traceFlag = true;
bool activeFlag = false;
namespace {
struct Info{
void* ptr;
const char* file;
long line;
};
const size_t MAXPTRS=10000u;
Info memMap[MAXPTRS];
size_t nptrs=0;
int findPtr(void* p){
for(size_t i=0;i<nptrs;++i)
if(memMap[i].ptr==p)
return i;
return -1;
}
void delPtr(void* p){
int pos=findPtr(p);
assert(pos>=0);
for(size_t i=pos;i<nptrs-1;++i)
memMap[i]=memMap[i+1];
--nptrs;
}
struct Sentinel{
~Sentinel(){
if(nptrs>0){
printf("Leak memory at:/n");
for(size_t i=0;i<nptrs;i++)
printf("/t%p(file:%s,line %ld)/n",
memMap[i].ptr,memMap[i].file,memMap[i].line);
}
else
printf("No user memory leaks/n");
}
};
Sentinel s;
}//end of anonymous namespace
void*
operator new(size_t siz,const char* file ,long line){
void* p=malloc(siz);
if(activeFlag){
if(nptrs==MAXPTRS){
printf("memory map too small(intcrease MAXPTRS)/n");
exit(1);
}
memMap[nptrs].ptr=p;
memMap[nptrs].file=file;
memMap[nptrs].line=line;
++nptrs;
}
if(traceFlag){
printf("Allocate %u bytes at address %p",siz,p);
printf("(file: %s,line : %ld)/n",file,line);
}
return p;
}
void*
operator new[](size_t siz,const char* file,long line){
return operator new(siz,file,line);
}
void operator delete(void *p){
if(findPtr(p)>=0){
free(p);
assert(nptrs>0);
delPtr(p);
if(traceFlag)
printf("Deleted memory at address %p/n",p);
}
else if(!p && activeFlag)
printf("Attempt to delete unknown pointer:%p/n",p);
}
void operator delete[](void *p){
operator delete(p);
}
生出动态链接库 g++ -shared -fpic libmemcheck.so
调用的时候g++ xx.cpp -L. -lmemcheck
效果很好,有个对比,size一下
text data bss dec hex filename
7664 388 120204 128256 1f500 a.out
text data bss dec hex filename
6176 380 180 6736 1a50 a.out
但是有个问题阿,只能把so文件扔到/usr/lib 下,才可以跑,否则找不到。牛人帮忙阿~!