zoukankan      html  css  js  c++  java
  • C++的内存泄漏检测

    C++大量的手动分配、回收内存是存在风险的,也许一个函数中一小块内存泄漏被重复放大之后,最后掏空内存。

    这里介绍一种在debug模式下测试内存泄漏的方法。

    首先在文件的开头以确定的顺序写下这段代码:

    1 #define _CRTDBG_MAP_ALLOC
    2 #include <crtdbg.h>
    3 #include <stdlib.h>

    第1行定义了宏,实现一些内存分配函数向debug模式的映射。

    打开<crtdbg.h>我们可以找到这么一段代码:

    可以看到,定义了_DEBUG情况下,定义_CRTDBG_MAP_ALLOC会将函数映射为_dbg的版本。

    第二个步骤,对new做一个重定义

    1 #define NEW_WITH_MEMORY_LEAK_CHECKING new(_NORMAL_BLOCK,__FILE__,__LINE__)
    2 #define new    NEW_WITH_MEMORY_LEAK_CHECKING

    这里new采用的是VC++对operator new的一个重载,可以在<vcruntime_new_debug.h>中找到,这里不多讲了。

    完成以上两步之后,程序中new和delete回收的过程便被VC++监视了,在程序退出的地方采用

    1 _CrtDumpMemoryLeaks();

    便可以在“输出”窗口查看报告了。

    举个栗子

     1 #define _CRTDBG_MAP_ALLOC
     2 #include <stdlib.h>
     3 #include <crtdbg.h>
     4 #define NEW_WITH_MEMORY_LEAK_CHECKING new(_NORMAL_BLOCK,__FILE__,__LINE__)
     5 #define new    NEW_WITH_MEMORY_LEAK_CHECKING
     6 
     7 int main()
     8 {
     9     auto p = new int[10];
    10     _CrtDumpMemoryLeaks();
    11     return 0;
    12 }

    这里还有一点,VC++的编译器cl.exe在delete之后会将内存置为0xcdcd防止再次利用,这里显然是程序结束时对p进行了回收。

    此外,还要介绍一个new的玩法。

    (尤其标准库中很突出)C++程序使用了placement new,这里我不是要介绍这个用法,想了解的自行。

    placement new在new后边跟了括号,这会和上面提到的VC++重载的new冲突,那么怎么避免,在其他地方宏定义了新的new而和placement new冲突的情况?

    相信大家一定见过像下面的代码

    1 #pragma push_macro("new")
    2 #undef new
    3 //using the raw new
    4 #pragma pop_macro("new")

    #pragma push/pop_macro将宏定义名压/弹栈,这里现将宏new压栈,保留原来的定义,之后取消定义,使用原生的new,使用完毕后弹栈恢复宏定义。

    以上是我介绍的对new出来的内存进行泄漏检测的简单方法,以及延伸出的一点常用技巧。

    感谢阅读

  • 相关阅读:
    编程谜题:提升你解决问题的训练场
    同态加密实现数据隐私计算,能让你的小秘密更加秘密
    interviewstreet pair
    x & (x 1)==0
    uva 11991 Easy Problem from Rujia Liu?
    hdoj 1230 火星A+B
    hdoj 1711 KMP Number Sequence
    HackerRank网站,为编码程序员们提供一个以编码谜题和现实生活中遇到的编码难题为基础的新兴的社交平台
    ACM博弈知识汇总
    hdoj 1202 水水更健康
  • 原文地址:https://www.cnblogs.com/jily/p/6239514.html
Copyright © 2011-2022 走看看