设为首页 加入收藏

TOP

如何定位c++内存泄露
2013-04-10 11:40:26 来源: 作者: 【 】 浏览:200
Tags:如何 定位 内存 泄露

  在进行C++(www.cppentry.com)开发时,如果在windows平台上,使用MFC,则可以自动检测内存泄露,如果是win32或者console程序,不使用MFC,则需要自己进行处理。

  下面是在总结的一些方法,均来自网上,也经历了实际检验,在此备份。

  1.  利用 KDetectMemoryLeak.h来完成类似MFC重定义NEW宏的效果。可以完成泄露点的输出。

  在代码的最后,采用_CrtDumpMemoryLeaks();

  具体可以参见《VS2008内存泄露检测》文档,作者写的很清楚,在此谢谢。

  KDetectMemoryLeak.h 源码:

  #pragma once

  #ifdef _DEBUG

  #define DEBUG_CLIENTBLOCK    new( _CLIENT_BLOCK, __FILE__,__LINE__)

  #else

  #define DEBUG_CLIENTBLOCK

  #endif

  #define _CRTDBG_MAP_ALLOC

  #include <stdlib.h>

  #include <crtdbg.h>

  #ifdef _DEBUG

  #define new DEBUG_CLIENTBLOCK

  #endif

  2.  对于无法定位到具体源代码的泄露,可以通过分析dump出来的信息来定位。

  特别是在DLL库中,经常会出现这种情况。

  比如:

  {152} normal block at 0x01078320, 12 bytes long.

  Data: 08 79 65 00 48 82 07 01 00 00 00 00

  {151} normal block at 0x010782C0, 36 bytes long.

  Data: CD CD CD CD CD CD CD CD 00 00 00 00 00 00 0000

  {150} normal block at 0x01078248, 56 bytes long.

  Data: F4 77 65 00 00 00 00 00 68 71 07 01 90 3A 0910

  《软件调试》的702页介绍了堆块转储的细节,取其中的一个堆块为例:

  {137} normal block at 0x01073790, 8 bytes long.

  Data: <H7> 48 37 07 01 CD CD CD CD

  137是堆块的分配序号,堆块的类型为普通堆块,位置为0x01073790,用户区长度为8字节。

  Data后为用户数据区的前16字节,因为这个数据区只有8字节,所以即所有8字节。<H7>是这8字节的ASCII码显示(其它6字节为不可显示的ASCII码)。其中的CD CD CDCD 是CRT在分配堆块时自动填充的固定内容(《软件调试》P696)。这说明这8个字节的堆块,应用程序使用过前4个字节,后四个字节没有使用过。

  对于这样的内存泄漏,有很多种办法,你首先可以试一下23.13.1节介绍的内存分配序号断点,也就是重新运行程序,在尽可能早的时候(比如入口),设置序号断点(将_crtBreakAlloc变量设置为要中断的序号,比如137),让CRT分配到指定的内存块时中断。中断下来后,可以根据栈回溯判断是哪个模块在分配内存,记录后,再退出程序,如果这个堆块仍出现在转储列表中,那么刚才那个模块便值得怀疑了。

  如果你有被怀疑的模块源代码,那么可以使用23.15.3节介绍的方法让堆块转储信息中包含源程序的文件名和行号,即下面的样子:

  C:\dig\dbg\author\code\chap23\MemLeak\MemLeak.cpp(22): {74} normal block at 0x00371000, 20 bytes long.

  Data: CD CD CD CD CD CD CD CD CD CD CD CD CD CD CDCD

  3.可以利用 vld 进行检测。

  4.还可以利用 boundcheck,purify等工具进行检测。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇指针引用 下一篇c++实现欧拉回路问题

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: