内存泄露检测
指针异常
空指针
- 编译器可发现
野指针(空悬指针)
- 代码规范好习惯可以规避
内存泄露
- 排查困难
内存泄露的检测
在每个头文件中加入 #include "DebugNew.h 头文件即可, 仅在DEBUG下有效.
代码如下:
// TracerNew.h
#ifndef _TRACER_NEW_H_
#define _TRACER_NEW_H_
#ifndef NDEBUG
#include <map>
// 全局重载new
void* operator new (size_t nSize, const char* szFile, long lLine);
// 全局重载delete
void operator delete(void* p);
class TracerNew
{
class TracerNewInfo
{
public:
TracerNewInfo(const char* szFile = nullptr, long lLine = 0);
const char* File() const;
long Line() const;
private:
const char* szFile_;
long lLine_;
};
class Lock
{
public:
Lock(TracerNew& tracer) : tracer_(tracer)
{
++tracer_.lLockCount_;
}
~Lock()
{
--tracer_.lLockCount_;
}
private:
TracerNew& tracer_;
};
public:
TracerNew();
~TracerNew();
void Add(void* p, const char* szFile, long lLine);
void Remove(void* p);
void Dump();
static bool Ready;
private:
std::map<void*, TracerNewInfo> tracerInfos_;
long lLockCount_;
};
extern TracerNew newTracer;
#endif // !NDEBUG
#endif // !_TRACER_NEW_H_
// TracerNew.cpp
#include "TracerNew.h"
#ifndef NDEBUG
#include <cstdlib>
#include <iostream>
TracerNew newTracer;
bool TracerNew::Ready = false;
void* operator new(size_t nSize, const char * szFile, long lLine)
{
void* p = malloc(nSize);
// 开始记录
if (TracerNew::Ready)
newTracer.Add(p, szFile, lLine);
return p;
}
void operator delete(void * p)
{
if (TracerNew::Ready)
newTracer.Remove(p);
free(p);
}
TracerNew::TracerNew() : lLockCount_(0)
{
TracerNew::Ready = true;
}
TracerNew::~TracerNew()
{
TracerNew::Ready = false;
Dump();
}
void TracerNew::Add(void* p, const char * szFile, long lLine)
{
if (lLockCount_ > 0)
return;
//++lLockCount_;
Lock l(*this);
tracerInfos_[p] = TracerNewInfo(szFile, lLine);
//--lLockCount_;
}
void TracerNew::Remove(void * p)
{
if (lLockCount_ > 0)
return;
//++lLockCount_;
Lock l(*this);
auto iter = tracerInfos_.find(p);
if (iter != tracerInfos_.end())
{
// 找到了
tracerInfos_.erase(p);
}
//--lLockCount_;
}
void TracerNew::Dump()
{
for each (auto tracerInfo in tracerInfos_)
{
std::cout << "0x" << tracerInfo.first << ":\t"
<< tracerInfo.second.File() << "\t In Line:"
<< tracerInfo.second.Line() << std::endl;
}
}
TracerNew::TracerNewInfo::TracerNewInfo(const char * szFile, long lLine)
: szFile_(szFile), lLine_(lLine)
{
}
const char* TracerNew::TracerNewInfo::File() const
{
return szFile_;
}
long TracerNew::TracerNewInfo::Line() const
{
return lLine_;
}
#endif // !NDEBUG
// DebugNew.h
#ifndef _DEBUG_NEW_H_
#define _DEBUG_NEW_H_
#ifndef NDEBUG
#include "TracerNew.h"
#define new new(__FILE__, __LINE__)
#endif // !NDEBUG
#endif // !_DEBUG_NEW_H_
如有错误,请提出指正!谢谢.
本文由 花心胡萝卜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2017-02-25 at 02:20 pm