#pragma once
#include <map>
//TracerNew.h
void* operator new(size_t size, const char* file, long line);
void* operator new(size_t size);
void operator delete(void* p);
class TracerNew
{
class TracerNewInfo
{
public:
TracerNewInfo(const char* file = nullptr, long line = 0):_file(file),_line(line){}
const char* File() const;
long Line() const;
private:
const char* _file;
long _line;
};
class Lock
{
public:
Lock(TracerNew& tracerNew):_tracerNew(tracerNew)
{
_tracerNew.lockCount++;
}
~Lock()
{
_tracerNew.lockCount--;
}
private:
TracerNew& _tracerNew;
};
public:
TracerNew();
~TracerNew();
void Add(void* p, const char*file, long line);
void Remove(void* p);
void Dump();
public:
static bool isReady;
private:
std::map<void*, TracerNewInfo> tracerInfos;
long lockCount;
};
extern TracerNew NewTracer;
//////////////////////////////////////////////////////////////
//TracerNew.cpp
#include "TracerNew.h"
#include <cstdlib>
#include <iostream>
#include <QDebug>
TracerNew NewTracer;
void* operator new(size_t size, const char* file, long line)
{
void* p = malloc(size);
//开始记录
if (TracerNew::isReady)
{
NewTracer.Add(p, file, line);
}
return p;
}
void* operator new(size_t size)
{
void* p = malloc(size);
if (TracerNew::isReady)
{
NewTracer.Add(p, "UnKnow", -1);
}
return p;
}
void operator delete(void* p)
{
if (TracerNew::isReady)
NewTracer.Remove(p);
free(p);
}
bool TracerNew::isReady = false;
TracerNew::TracerNew() : lockCount(0)
{
TracerNew::isReady = true;
}
TracerNew::~TracerNew()
{
TracerNew::isReady = false;
Dump();
}
void TracerNew::Add(void* p, const char*file, long line)
{
//std::lock_guard<std::mutex> lock(mutex);
if (lockCount > 0) return;
Lock lock(*this);
tracerInfos[p] = TracerNewInfo{file, line};
}
void TracerNew::Remove(void* p)
{
if (lockCount > 0) return;
Lock lock(*this);
auto iter = tracerInfos.find(p);
if (iter != tracerInfos.end())
{
tracerInfos.erase(iter);
}
}
void TracerNew::Dump()
{
for (const auto& info :tracerInfos)
{
//std::cout << "0x" << info.first << "\t" << info.second.File() << "\t" << info.second.Line() << std::endl;
qDebug() << "0x" << info.first << "\t" << info.second.File() << "\t" << info.second.Line();
}
}
const char* TracerNew::TracerNewInfo::File() const
{
return _file;
}
long TracerNew::TracerNewInfo::Line() const
{
return _line;
}
//DebugNew.h
#pragma once
#include "TracerNew.h"
//void* operator new(size_t, const char*file, long line);
//
////全局的对象
////记录 new 记录
////delete 删除记录一次
//
////剩下的记录就是 内存泄漏了
#define new new(__FILE__, __LINE__)
//测试
#include "DebugNew.h"
#include <iostream>
class Test
{
public:
Test(){}
};
QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
Test* p = new Test;
TestFun();
}
void QtWidgetsApplication1::TestFun()
{
Test* p = new Test;
int* p2 = new int[10];
}
//结果
标签:泄漏,const,file,void,C++,内存,TracerNew,line,size From: https://www.cnblogs.com/kinglxg/p/17557647.html