下面介绍用重载new/delete运算符的方式来实现一个简单的内存泄露检测工具,基本思想是重载全局new/delete运算符,被检测代码调用new和delete运算符时就会调用重载过的operator new和operator delete,在重载的operator new里和operator delete里记录下内存申请和释放信息,从而判断内存使用情况。
下面一步步介绍它的实现!

1、全局new/delete的重载
    先看一下重载new/delete的规则:
        重载的operator new的参数个数任意,但第一个参数必须是size_t类型的,返回值必须是void*。重载operator delete只允许有一个参数,且是void*型。
    当然,不光要重载operator new 和 operator delete, 还要重载operator new [], operator delete [],更多operator new和operator delete重载的内容参考《Effective C++》
    重载的new/delete, new[]/delete[]代码如下:
    void * operator new (size_t size)
    {
        if(0 == size)
        {
            return 0;
        }
        void *p = malloc(size);
        return p;
    }
 
    void * operator new [](size_t size)
    {
        return operator new(size);
    }
 
    void operator delete (void * pointer)
    {
        if(0 != pointer)
        {
            free(pointer);
        }
    }
 
    void operator delete[](void * pointer)
    {
        operator delete(pointer);
    }
 
2、用__FILE__, __LINE__记录new的位置
    为了找到内存泄露的元凶,我要记录下每一处new所在的文件名和所在行。于是再次重载了operator new:
    void * operator new (size_t size, const char* file, const size_t line);
    void * operator new [](size_t size, const char* file, const size_t line);
    为了避免编译时出现warning C4291(没有与operator new(unsigned int,const char *,const unsigned int) 匹配的delete),又重载了
    void operator delete (void * pointer, const char* file, const size_t line);
    void operator delete[](void * pointer, const char* file, const size_t line);
    尽管我知道它没用①。
        
    我想到了用系统提供的__FILE__和 __LINE__宏获取当前文件名与行号,我试图把__FILE__和 __LINE__直接填到operator new和operator new[]函数体里边,然后把函数置成inline,结果都输出的是重载operator new和operator new[]的文件和函数体printf函数所在行。然后又试了将operator new的缺省参数设为__FILE__和 __LINE__结果依然,于是想到了用宏定义。

先看看MFC里的做法,MFC为了调试方便,对new进行了宏定义:
    #define new DEBUG_NEW
    #define DEBUG_NEW new(THIS_FILE, __LINE__)
     
    这里我借用MFC的做法,我也用宏定义:
    void * operator new (size_t size, const char* file, const size_t line);
    void * operator new [](size_t size, const char* file, const size_t line);
    #define MC_NEW new(__FILE__, __LINE__)
    #define new MC_NEW
 
 
3、将malloc/free 用new/delete替换
    为了便于统计malloc/free信息,也用宏定义的方法处理:
    #define malloc(s) ((void*)new unsigned char[s])
    #define free(p)   (delete [] (char*)(p));
 
4、在数据结构里存储内存使用情况。
    下面写一个用于存储new/delete中内存信息的数据结构,可以使用链表,也可以使用哈希表,这里选用哈希表,写一个CHash类。
代码略。
 
5、为了保证CHash在所有对象析构执行完之后再销毁,应该将CHash放在全局存储区,将其设成static类型,另外,如果有多个static,还需要注意放置的顺序。
 
到这里这个简易的内存泄露检测工具完成了,但目前还不能用于多线程。

①当两个operator new和operator delete有相等的参数个数,并且除了第一个参数之外其余参数的类型依次完全相同之时,我们称它们为一对匹配的operator new和operator delete。
  不过正常情况下带多个参数的delete不会被调用,只有在构建一个对象的过程中,构造函数中发生异常,并且这个异常被捕获了,那么此时C++的异常处理机制才会自动用与被使用的operator new匹配的operator delete来释放内存(补充一点:在operator new中抛出异常不会导致这样的动作,因为系统认为这标志着内存分配失败)。
  试验代码:
    #include <malloc.h>
    struct Base
    {
        Base()
        {
            throw int(3);
        }
        ~Base() {}
        void* operator new( size_t nSize, const char*,int)
        {
            void* p = malloc( nSize );
            return p;
        }
        void operator delete( void *p)
        {
            free(p);
        }
        void operator delete( void* p,const char*,int)
        {
            free( p );
        }
    };
    #define new new(__FILE__, __LINE__)
    int main( void )
    {
        Base* p = null;
        try
        {
            p = new Base;
            delete p;
        }
        catch(...)
        {
        }
        return 0;
    }

转载于:https://www.cnblogs.com/dongzhiquan/p/3310885.html

重载全局new/delete实现内存检测相关推荐

  1. 重载new、delete和强制类型转换运算符()

    1.重载new和delete运算符 内存管理运算符new.new[].delete和delete[]也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就 ...

  2. 通过从全局和类内部重载operator new /delete来获取内存管理权

    目录 1.通过重载获得内存管理权 2.容器的内存管理 3.重载new.array new.replacement new,接管内存控制权 1.重载全局::operator new / ::operat ...

  3. C++ 工程实践(2):不要重载全局 ::operator new()

    陈硕 (giantchen_AT_gmail) Blog.csdn.net/Solstice 本文只考虑 Linux x86 平台,服务端开发(不考虑 Windows 的跨 DLL 内存分配释放问题) ...

  4. 内存检测王者之剑—valgrind

    记得在大学的刚开始学习C/C++的时候,对于内存问题一点也没有关心过,其实也是关心比较少,知道后来才慢慢注意起来,当时排查是否有内存泄漏全靠手,去看看malloc和free或者new和delete是否 ...

  5. C/C++内存检测工具Sanitizers

    Sanitizers介绍 Sanitizers 是谷歌开源的内存检测工具,包括AddressSanitizer.MemorySanitizer.ThreadSanitizer.LeakSanitize ...

  6. 动态内存检测工具Valgrind

    1. Valgrind查找内存泄露利器 Valgrind是一个GPL的软件,用于Linux(For x86, amd64 and ppc32)程序的内存调试和代码剖析.你可以在它的环境中运行你的程序来 ...

  7. C++_重载new,delete

    C++_重载new,delete 这里重载的是new三步delete两步里的第一步操作,这点一定要注意,所以下面出现size可以直接malloc,可以看以前笔记 new表达式(new).operato ...

  8. 深入理解C++ new/delete, new []/delete[]动态内存管理

    在C语言中,我们写程序时,总是会有动态开辟内存的需求,每到这个时候我们就会想到用malloc/free 去从堆里面动态申请出来一段内存给我们用.但对这一块申请出来的内存,往往还需要我们对它进行稍许的& ...

  9. C/C++内存检测工具valgrind--memcheck

    Valgrind简介 Valgrind是运行在Linux上的一套基于仿真技术的程序调试和分析工具,作者是获得过Google-O'Reilly开源大奖的Julian Seward,它包含一个内核 -- ...

  10. 【Linux】内存检测工具Valgrind

    内存检测工具Valgrind Valgrind是运行在Linux上的一套基于仿真技术的程序调试和分析工具,作者是获得过Google-O'Reilly开源大奖的Julian Seward,它包含一个内核 ...

最新文章

  1. [转]远程唤醒技术在运维中的应用
  2. go包package的使用细节
  3. 卸载vuecli3_卸载vue2.0并升级vue_cli3.0的实例讲解
  4. android 仿qq it蓝豹,《IT蓝豹》listview实现各种版面设计功能
  5. solutions for 'No Suitable Driver Found For Jdbc'
  6. java final域_【Java】final 域的内存语义
  7. 智能优化算法:磷虾群算法-附代码
  8. 一个完美网站的101项指标.第二部分.内容为王
  9. Java项目--网页版音乐播放器(JQuery前端逻辑)
  10. 国防科技论坛,一个不错的技术资料分享网站
  11. 不允许一个用户使用一个以上用户名与服务器或共享资源的多重连接,中断与此服务器或共享资源的所有连接,然后再试一次
  12. Android App内部防截屏技术
  13. Pandas 元素选取
  14. 台式计算机用电视机做显示器,电脑怎么一次连接显示器和电视
  15. Arduino KY-024线性磁力霍尔传感器
  16. springboot logback配置included及时区设置问题
  17. php 根据银行卡号获取所属银行
  18. 达梦数据库DM8-DM管理工具介绍和简单使用
  19. (转)FFmpeg源代码简单分析:avformat_open_input()
  20. android studio 7200u,#本站首晒# 多图杀猫 华为MateBook X上手体验

热门文章

  1. WINDOWS各类执行程序的接口总结
  2. C# Excel 删除指定的工作表
  3. 双非计算机考研复试怎么办,【计算机考研】985、211VS双非,复试时导师会有歧视吗?...
  4. pythonfor循环是迭代器吗_Python学习——for循环,生成器,迭代器详解
  5. 太极图正确画法_什么是太极?其意义是什么?太极图是谁画的?
  6. Ubuntu 16虚拟机中 iptables操作
  7. Centos python2.6.6升级2.7.14
  8. 为什么我离开了管理岗位
  9. 使用Eclipse中提供的Refactor(重构)工具
  10. PHP使用MySQL数据库