自己实现malloc,在里面进行跟踪
valgrind、dmalloc、efence (linux)
visual leak detector(windows)
operator new
operator delete
new operator <=>operator new + 构造函数
头文件包含次序
C库、C++库、其他库.h 、项目中.h
//Tracer.h
#ifndef _TRACER_H_
#define _TRACER_H_
#include <map>
#ifndef NDEBUG
void* operator new(size_t size, const char* file, long line);
//void* operator new(size_t size);
void* operator new[](size_t size, const char* file, long line);
void* operator new[](size_t size);
void operator delete(void* p, const char*, long);
void operator delete(void* p);//重载
void operator delete[](void* p, const char*, long);//重载
void operator delete[](void* p);//重载
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_; }
private:
const char* file_;
long line_;
};
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_;
};
extern Tracer NewTrace;
#endif//NDEBUG
#endif
//Tracer.cpp
#include <iostream>
#include "Tracer.h"
#ifndef NDEBUG
bool Tracer::Ready = false;
Tracer::Tracer()
{
Ready = true;
}
Tracer::~Tracer()
{
Ready = false;
Dump();
}
void Tracer::Add(void* p, const char* file, long line)
{
mapEntry_[p] = Entry(file,line);
}
void Tracer::Remove(void* p)
{
std::map<void*, Entry>::const_iterator it;
it = mapEntry_.find(p);
if (it != mapEntry_.end())
{
mapEntry_.erase(it);
}
}
void Tracer::Dump()
{
if (mapEntry_.size()>0)
{
std::cout << "*** Memory leak(s):" << std::endl;
std::map<void*, Entry>::const_iterator it;
for (it = mapEntry_.begin(); it != mapEntry_.end(); ++it)
{
const char* file = it->second.File();
long line = it->second.Line();
int addr = reinterpret_cast<int>(it->first);
std::cout << "0x" << std::hex << 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);
}
return p;
}
void* operator new[](size_t size, const char* file, long line)
{
void* p = malloc(size);
if (Tracer::Ready)
{
NewTrace.Add(p, file, line);
}
return p;
}
void* operator new[](size_t size)
{
void* p = malloc(size);
if (Tracer::Ready)
{
NewTrace.Add(p, "?", 0);
}
return 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, const char*, long)
{
if (Tracer::Ready)
{
NewTrace.Remove(p);
}
free(p);
}
void operator delete(void* p)
{
if (Tracer::Ready)
{
NewTrace.Remove(p);
}
free(p);
}
void operator delete[](void*p, const char*, long)
{
if (Tracer::Ready)
{
NewTrace.Remove(p);
}
free(p);
}
void operator delete[](void*p)
{
if (Tracer::Ready)
{
NewTrace.Remove(p);
}
free(p);
}
#endif
//DebugNew.h
#ifndef _DEBUG_NEW_H_
#define _DEBUG_NEW_H_
#ifndef NDEBUG
#include "Tracer.h"
#define new new(__FILE__, __LINE__)
#endif
#endif
//main.cpp
#include<iostream>
using namespace std;
#include"DebugNew.h"
int main(void)
{
int* p = new int;//堆栈开辟四个字节的空间
//delete p;
int* p2 = new int[5];
//delete[] p2;
return 0;
}
解决程序运行终止的问题
//Tracer.h
#ifndef _TRACER_H_
#define _TRACER_H_
#include <map>
#ifndef NDEBUG
void* operator new(size_t size, const char* file, long line);
void* operator new(size_t size);
void* operator new[](size_t size, const char* file, long line);
void* operator new[](size_t size);
void operator delete(void* p, const char*, long);
void operator delete(void* p);//重载
void operator delete[](void* p, const char*, long);//重载
void operator delete[](void* p);//重载
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_; }
private:
const char* file_;
long line_;
};
class Lock
{
public:
Lock(Tracer& tracer) :tracer_(tracer)
{
tracer_.lock();
}
~Lock()
{
tracer_.unlock();
}
private:
Tracer& tracer_;
};
friend class Lock;
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 NewTrace;
#endif//NDEBUG
#endif
//Tracer.cpp
#include <iostream>
#include "Tracer.h"
#ifndef NDEBUG
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::Lock lock(*this);
mapEntry_[p] = Entry(file,line);
}
void Tracer::Remove(void* p)
{
if (lockCount_ > 0)
return;
Tracer::Lock lock(*this);
std::map<void*, Entry>::const_iterator it;
it = mapEntry_.find(p);
if (it != mapEntry_.end())
{
mapEntry_.erase(it);
}
}
void Tracer::Dump()
{
if (mapEntry_.size()>0)
{
std::cout << "*** Memory leak(s):" << std::endl;
std::map<void*, Entry>::const_iterator it;
for (it = mapEntry_.begin(); it != mapEntry_.end(); ++it)
{
const char* file = it->second.File();
long line = it->second.Line();
int addr = reinterpret_cast<int>(it->first);
std::cout << "0x" << std::hex << 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);
}
return p;
}
void* operator new[](size_t size, const char* file, long line)
{
void* p = malloc(size);
if (Tracer::Ready)
{
NewTrace.Add(p, file, line);
}
return p;
}
void* operator new[](size_t size)
{
void* p = malloc(size);
if (Tracer::Ready)
{
NewTrace.Add(p, "?", 0);
}
return 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, const char*, long)
{
if (Tracer::Ready)
{
NewTrace.Remove(p);
}
free(p);
}
void operator delete(void* p)
{
if (Tracer::Ready)
{
NewTrace.Remove(p);
}
free(p);
}
void operator delete[](void*p, const char*, long)
{
if (Tracer::Ready)
{
NewTrace.Remove(p);
}
free(p);
}
void operator delete[](void*p)
{
if (Tracer::Ready)
{
NewTrace.Remove(p);
}
free(p);
}
#endif
//DebugNew.h
#ifndef _DEBUG_NEW_H_
#define _DEBUG_NEW_H_
#ifndef NDEBUG
#include "Tracer.h"
#define new new(__FILE__, __LINE__)
#endif
#endif
//main.cpp
#include<iostream>
using namespace std;
#include"DebugNew.h"
int main(void)
{
int* p = new int;//堆栈开辟四个字节的空间
//delete p;
int* p2 = new int[5];
//delete[] p2;
return 0;
}