zoukankan      html  css  js  c++  java
  • VC++ 内存泄露与检测的一种方法

        本文介绍,当VC++或者MFC程序,出现内存泄露时,如何快速定位的方法,这种方法有一定的局限性,在注意事项中会给出的。

    MFC程序

        当MFC程序出现内存泄露时,退出程序时的VS调试输出窗口,一般会有如下显示:

    image

       上面显示了在程序的哪个文件的哪行语句,发生了内存泄露,其中:

       {345}: 表示 内存分配编号

       normal block:表示 内存块类型,有普通块(普通程序分配)、客户端块(分配基于CObject的内存)和CRT块(库函数内部分配)这几种类型

       0x0074A030:以16进制形式输出的内存位置

       40 bytes long: 以字节为单位的内存块大小

       Data<   >CD CD ..:内存块前16个字节的内容,16进制表示。

          定位内存泄露位置,可以双击泄露信息,也可以在输出窗口 按F4键,跳转到 出错行。

     

    普通VC++程序

        在普通VC++程序中,要类似MFC中内存检测的效果,需要做如下操作。

        1.  在头文件中,添加  #include <ctrdbg.h>

        2.  在程序入口最开始处,添加 下面两句话即可

            _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );    //设置调试堆函数跟踪分配的方式
            //_CrtSetBreakAlloc();     //这句话,在确实有内存泄露的情况下,给 内存分配编号

        3. 按F5,运行程序,等待程序退出后,在输出窗口可以看到下面的情况:

          image

         如图所示,程序有两处内存泄露地方,分配编号为 476 和 475,此时,给_CrtSetBreakAlloc()函数传入476参数,再次运行程序,在退出时,会弹出如下窗口:

         image

    点击 中断  跳到,_CrtSetBreakAlloc()中断的地方,然后在程序中,通过查看调用堆栈,就可以看到应用程序的哪一次new操作没有执行delete操作。

    在中断的同时,也可以从控制台中,看到整个程序析构的顺序,如下图所示:

    image

     

    注意事项

    1. 当程序确认没有内存泄露时,不可以调用_CrtSetBreakAlloc(475),因为,这样会在指定内存分配次数发生时,强制中断程序。

    2. 这种检测内存分配的方式,要求,程序在执行过程中,是可还原的(多次执行过程的内存分配顺序不会发送变化),这个假设,在多数情况下是成立的,不过,在多线程执行的环境下,有时候难以保证。

    3. 对于普通C程序,上述检测方法也是成立的,只不过new换成了malloc,delete换成了free

    4. 比如 int *p = new int[4]; delete p; 这种方式的泄露,上述方法是检测不出来,此时,需要cppcheck等更有力的工具来检查。

     

    参考链接:C++调试堆

  • 相关阅读:
    使用过滤器(Filter)解决请求参数中文乱码问题(复杂方式)
    JDBC-自定义数据库工具类(DBService)
    Dbutils学习(介绍和入门)
    JAVA中简单的MD5加密类(MD5Utils)
    TCP/IP网络编程系列之三(初级)
    Linux C编程学习
    sharepoint 2010 创建自定义的ASP.NET Web Service (上)
    TCP/IP网络编程系列之四(初级)
    TCP/IP网络编程系列之二(初级)
    TCP/IP网络编程系列之一(初级)
  • 原文地址:https://www.cnblogs.com/cherishui/p/4637118.html
Copyright © 2011-2022 走看看