内存泄漏检测两种方式
1.valgrind命令 检测内存泄漏
2.通过重写new和delete检测,详细代码见附件tracer.tar.gz。执行命令:g++ Tracer.cpp main.cpp -std=c++11 -o test;
./test执行即可检测内存泄漏
DebugNew.h
#ifndef _DEBUG_NEW_H_
#define _DEBUG_NEW_H_
#ifndef DEBUG
#include "Tracer.h"
#define new new(__FILE__, __LINE__)
#endif // DEBUG
#endif // _DEBUG_NEW_H_
Tracer.h
#ifndef _TRACER_H_
#define _TRACER_H_
#ifndef DUBUG
#include <map>
void* operator new(size_t size, const char* file, long line);
void operator delete(void* p, const char* file, long line);
void* operator new(size_t size);
void operator delete(void *p) noexcept;
void* operator new[](std::size_t, const char* file, long line);
void operator delete[](void *p,const char* ,long ) noexcept;
void* operator new[](std::size_t);
void operator delete[](void *p) noexcept;
class Tracer {
private:
class Entry {
public:
Entry(const char* file=0, long line=0)
:file_(file), line_(line) {}
const char* File() const { return file_; }
long Line() const { return line_; }
public:
const char* file_;
long line_;
};
class AutoLock {
public:
AutoLock(Tracer& tracer):tracer_(tracer) {
tracer_.Lock();
}
~AutoLock() {
tracer_.UnLock();
}
private:
Tracer& tracer_;
};
public:
Tracer();
~Tracer();
static bool Ready;
void Add(void* p, const char* file, long line);
void Remove(void* p);
void Dump();
private:
std::map<void*, Entry> mapEntry_;
int lockCount_;
void Lock() { ++lockCount_; }
void UnLock() { --lockCount_; }
};
extern Tracer NewTracer;
#endif // DEBUG
#endif // _TRACER_H_
Tracer.cpp
#include <iostream>
#include "Tracer.h"
#ifndef DEBUG
bool Tracer::Ready = false;
Tracer::Tracer():lockCount_(0) {
Ready = true;
}
Tracer::~Tracer() {
Ready = false;
Dump();
}
void Tracer::Add(void* p, const char* file, long line) {
if(lockCount_ > 0) {
return ;
}
Tracer::AutoLock lock(*this);
//Lock();
mapEntry_[p] = Entry(file, line);
//UnLock();
}
void Tracer::Remove(void* p) {
if(lockCount_ > 0) {
return ;
}
Tracer::AutoLock lock(*this);
//Lock();
std::map<void*, Entry>::iterator it;
it = mapEntry_.find(p);
if(it != mapEntry_.end()) {
mapEntry_.erase(it);
}
//UnLock();
}
void Tracer::Dump() {
if(mapEntry_.size() > 0) {
std::cout << "*** Memory leak(s):" << std::endl;
std::map<void*, Entry>::iterator it = mapEntry_.begin();
for(it = mapEntry_.begin(); it != mapEntry_.end(); ++it) {
const char* file = it->second.File();
long line = it->second.Line();
void* addr = it->first;
//int* addr = reinterpret_cast<int*>(it->first);
//std::cout << "0x" << std::hex << addr << ":"
std::cout << addr << ":"
<< file << ",line" << std::dec << line << std::endl;
}
std::cout << std::endl;
}
}
Tracer NewTrace;
void* operator new(size_t size, const char* file, long line) {
void* p = malloc(size);
if(Tracer::Ready) {
NewTrace.Add(p, file, line);
}
//std::cout << "operator new(size_t size, const char* file, long line)" << std::endl;
return p;
}
void operator delete(void* p, const char* file, long line) {
if(Tracer::Ready) {
NewTrace.Remove(p);
}
free(p);
}
void* operator new(size_t size) {
void* p = malloc(size);
if(Tracer::Ready) {
NewTrace.Add(p, "?", 0);
}
return p;
}
void operator delete(void *p) noexcept {
//void operator delete(void *p) {
if(Tracer::Ready) {
NewTrace.Remove(p);
}
//std::cout << "delete(void *p) noexcept" << std::endl;
free(p);
}
void* operator new [](std::size_t size, const char* file, long line) {
void* p = malloc(size);
if(Tracer::Ready) {
NewTrace.Add(p, file, line);
}
//std::cout << "operator new [](std::size_t size, const char* file, long line)" << std::endl;
return p;
}
void operator delete[](void *p, const char*, long) noexcept {
if(Tracer::Ready) {
NewTrace.Remove(p);
}
free(p);
}
void* operator new[](std::size_t size) {
void* p = malloc(size);
if(Tracer::Ready) {
NewTrace.Add(p, "?", 0);
}
//std::cout << "operator new[](std::size_t)" << std::endl;
return p;
}
void operator delete[](void *p) noexcept {
if(Tracer::Ready) {
NewTrace.Remove(p);
}
//std::cout << "delete[](void *p) noexcept" << std::endl;
free(p);
}
#endif // DEBUG
main.cpp
#include <iostream>
using namespace std;
#include "DebugNew.h"
int main(void) {
int* p = new int;
//cout << p << endl;
//delete p;
int* p2 = new int[5];
//delete []p2;
return 0;
}
//new(__FILE__, __LINE__) int