首页 > 系统相关 >C++内存泄漏检测

C++内存泄漏检测

时间:2023-07-16 11:55:21浏览次数:44  
标签:泄漏 const file void C++ 内存 TracerNew line size

#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

相关文章

  • 关于c++的右值引用
    引用Areferencecanbethoughtofasanameofanobject.左值引用:引用左值.右值引用:引用右值,用于参数传递,函数返回值,表达式中间结果.类似于常量引用,但是可以被修改.(左值)引用类型的变量只能绑定到左值表达式,只有const引用可以绑定到右值.右值引......
  • c++类型转换与RTTI运行阶段类型识别
    我们都知道C++完全兼容C语言,C语言的转换方式很简单,可以在任意类型之间转换,但这也恰恰是缺点,因为极其不安全,可能不经意间将指向const对象的指针转换成非const对象的指针,可能将基类对象指针转成了派生类对象的指针,这种转换很容易出bug,需要严格审查代码才能消除这种隐患,但是C这种转换......
  • lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /home/liuj
     glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。由于glibc囊括了几乎所有的 UNIX 通行的标准,可以想见其内容包罗万象。而......
  • C++ lambda函数
    一、格式大括号内是变量捕获,小括号内是参数列表。变量捕获的来源都是当前位置“能看得见”的变量。二、变量捕获上图左:将它“能看得见”的变量都按引用捕获。上图右:将它“能看得见”的变量都按值捕获。比如某个lambda表达式在语句块内,但是它全体引用捕获的话可以捕获全局......
  • 【性能测试】性能监控-python编写(CPU | 内存 | 磁盘io)占比监控脚本
    一、主要通过Python脚本实现对linux环境(CPU|内存|磁盘io)监控脚本示例:importtimeimportsubprocess#获取CPU使用率defget_cpu_usage():#系统CPU占比=系统态占比+空闲态占比=3.2%+36.5%=39.7%cpu_usage=subprocess.check_output("top-bn1......
  • JVM内存模型和类加载
    内存模型JVM内存模型主要分为堆、程序计数器、方法区、虚拟机栈和本地方法栈。堆堆中包含了字符串常量池。程序计数器记录线程执行的字节码的地址。方法区存放已被虚拟机加载的类相关信息,包括类信息、运行时常量池(存放编译生成的字面量和符号引用)。当类加载到内存后,JVM把......
  • VS2015 C++代码内存泄漏
    在可能泄漏的文件头部加入下面几行(保证malloc和new的泄漏都可以检测到)#define_CRTDBG_MAP_ALLOC#include<crtdbg.h>#ifdef_DEBUG//重载new运算符#definenewnew(_NORMAL_BLOCK,__FILE__,__LINE__)#endif程序运行起始位置:_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_C......
  • 105.C++初始化
    105.C++初始化C++中变量的初始化有很多种方式,如:默认初始化,值初始化,直接初始化,拷贝初始化,列表初始化。1.默认初始化默认初始化是指定义变量时没有指定初值时进行的初始化操作。默认初始化变量的值与变量的类型与变量定义的位置有关系:1.1内置类型变量对于内置类型变量(如in......
  • 81.哪些操作会造成内存泄漏
    81.哪些操作会造成内存泄漏?相关知识点:1.意外的全局变量2.被遗忘的计时器或回调函数3.脱离DOM的引用4.闭包回答:第一种情况是我们由于使用未声明的变量,而意外的创建了一个全局变量,而使这个变量一直留在内存中无法被回收。第二种情况是我们设置了setInterval定时器,而......
  • Grpc C++使用总结
    Grpc一,安装安装依赖sudoapt-getinstallpkg-configsudoapt-getinstallautoconfautomakelibtoolmakeg++unzipsudoapt-getinstalllibgfalgs-devlibgtest-devsudoapt-getinstallclanglibc++-dev下载gRPCgitclonehttps://github.com/grpc/grpc.gitc......