zoukankan      html  css  js  c++  java
  • 用CRT查找内存泄漏

    引用原文地址

    https://msdn.microsoft.com/en-us/library/x98tx3cf.aspx

    1. 在program中严格按下面顺序include

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

    2. 必须是Debug版的build

    Q : LiteServer遍Debug可能会遇到一些问题

    A : 可以用来验证Memcheck是否有误报。

        可以在对应的地址处下断点(会频繁断在malloc上,需要根据size下条件断点)

    Q : code在Release和Debug版下可能会不一样,最后可能会出现一个有memory leak一个没有

    3. "#define _CRTDBG_MAP_ALLOC"这个宏不能省略,否则memory leak的dump会缺少一些细节(如leak的code位置信息)

    4. 在app exit前,可以调用这个function打印memory leak report

    _CrtDumpMemoryLeaks();

    Q : 如果是全局或静态obj,在exit前其还未释放,此时report不会造成误报吗?

    A :不会

    5. 如果app有多个exits,你是不需要call _CrtDumpMemoryLeaks()在每个exit位置的。在app开始的位置call下面这个_CrtSetDbgFlag(),其会自动在每个exit的位置自动call _CrtDumpMemoryLeaks()

    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

    6. 默认情况下,memory leak的report会在VS Studio Debug窗的Output窗口中,可以用_CrtSetReportMode()将其重定向到其他位置。

    7. Report格式

    Detected memory leaks!
    
    Dumping objects ->
    
    c:usersusernamedocumentsprojectsleaktestleaktest.cpp(20) : {18}               //{18} : memory分配序号 
    
    normal block at 0x00780E80, 64 bytes long.                                         //64 bytes : block的大小(并不是分配时指定的大小,因为分配的heap由于会添加堆头堆尾等额外信息,会比分配时指定的size要大) 
    
    Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
    
    Object dump complete.
    
     

    Q : 发现即使按照第一条中的定义,也不会输出memory leak的行信息。

    A : 这个crtdbg对new处理不好,其block的地址只会new调用macro的地址,可用如下宏DBG_NEW来替代new,以打印出对应的行信息

    #ifdef _DEBUG
    
        #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
    
        // Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the 
    
        // allocations to be of _CLIENT_BLOCK type 
    
    #else
    
        #define DBG_NEW new
    
    #endif
    

    Q : 需要替换所有的源码,而且第三方库怎么办?

    Q : 没有栈回溯信息,多层调用怎么查找源头信息?

    A :  Debug,在app入口断下后,在watch窗口输入"_crtBreakAlloc"(如果"Runtime Library"是"/MD",则还需要添加"{,,ucrtbased.dll}_crtBreakAlloc"),这个值应该是"-1",修改成detect到的memory leak的分配序号(如7中的{18}),当分配该大小的memory时就会断下来(注意,重跑后的条件要和第一次获取分配序号的一致)。

        另外,在code中也可以直接指定:

    _crtBreakAlloc = 18;
    
        or :
    
    _CrtSetBreakAlloc(18);
    

    8. Test

    1> code

    #include <memory>
    
    std ::tr1 ::shared_ptr <int >   sp_nTest;
    
    void  Test ()
    {
          sp_nTest. reset( new int( 0x88));
    
          //memory leak
          int*  pnTest = new int( 0xCC);
    
          void* pMalloc = malloc( sizeof( int));
    }
    

    2> result

    Detected memory leaks!
    
    Dumping objects ->
    
    d:codesvs2010	estdetectmemleakconsole	est.cpp(14) : {65} normal block at 0x007B18A8, 4 bytes long.
    
    Data: <    > CD CD CD CD
    
    
    {64} normal block at 0x007B4F90, 4 bytes long.
    Data: <    > CC 00 00 00
    
    Object dump complete.
    

    红色部分是new出来的memory leak,可见并不会报出对应的code的行号

  • 相关阅读:
    oldboy_09_03day_test1
    oldboy_09_03day
    java消息队列
    es6语法([...arr], set/map数据结构,数组扩展,箭头函数等)
    Angular 2 Expression Changed After It Has Been Checked Exception
    jQuery之Deferred对象详解
    js面向对象:Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
    Angular 4.x 动态创建组件
    JS中this的四种用法
    typescript主键自增长
  • 原文地址:https://www.cnblogs.com/organic/p/7868153.html
Copyright © 2011-2022 走看看