lxg

导航

 

#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];
}

 //结果

 

posted on 2023-07-16 11:47  lxg_7105  阅读(32)  评论(0编辑  收藏  举报