在VisualC 中检测和隔离内存泄漏

2008-04-09 04:09:29来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

  具有动态的分配和释放内存的能力是C/C 程序语言的重要特色之一。VisualC debugger和CRT库提供了一系列有效的检测和鉴定内存泄漏的工具。

   设置内存泄漏检测

  检测内存泄漏的基本工具是调试器和CRT调试堆函数。为了使用调试堆函数,在你的程序中你必须含有下面的说明:

#define _CRTDBG_MAP_ALLOC
#include<stdlib.h>
#include<crtdbg.h>
  必须保证上面声明的顺序,如果改变了顺序,可能不能正常工作。<crtdbg.h>的_malloc_dbg和_free_dbg将取代标准的malloc和free函数出现在DEBUG版中,它可以跟踪内存的分配和释放。但是这只会在DEBUG版本中发生(当#define _DEBUG的时候),而Release版本仍使用标准的malloc和free功能。

#define _CRTDBG_MAP_ALLOC表示使用CRT堆函数的相应的DEBUG版本。这个定义不是必须的,但是没有它,内存泄漏报告含有的只是没有什么用处的信息。

  一旦你已经添加了刚才的声明,你就能够通过在程序中加入下面的代码来报告内存泄漏信息:

_CrtDumpMemoryLeaks();
  当在DEBUG模式下运行程序时,在Output窗口的Debug标签处_CrtDumpMemoryLeaks会显示内存泄漏的信息,例如:

Detected memory leaks!
Dumping objects ->
C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18} normal block at 0x00780E80, 64 bytes long.
Data:< > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
  如果没有#define _CRTDBG_MAP_ALLOC,内存泄漏报告就会像下面这样:

Detected memory leaks!
Dumping objects ->
{18} normal block at 0x00780E80, 64 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
  由此可见,定义_CRTDBG_MAP_ALLOC时,_CrtDumpMemoryLeaks可以提供更多的有用信息。

  如果没有定义_CRTDBG_MAP_ALLOC,那么内存泄漏报告如下显示:

   内存分配数值(花括号内)
   模块的类型(normal、client或者CRT)
   以十六进制格式定位的内存
   以字节计模块的大小
   第一个十六字节的内容(也可以用十六进制)

  如果定义了_CRTDBG_MAP_ALLOC,报告的内容还包括出现分配所泄漏内存的文件。在文件名之后括号内的数字是文件内的行数值。

  此时双击包含行数值和文件名的输出行, 或者选择输出行并按F4:

C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18} normal block at 0x00780E80, 64 bytes long.

  编辑窗口将会跳到文件中分配所泄漏内存的那一行代码,leaktest.cpp中的行号为20的那一行。

   使用_CrtSetDbgFlag

  如果你的程序只在一个地方退出,那么在选择调用_CrtDumpMemoryLeaks的位置是非常容易的。但是,如果你的程序可能会在程序多处位置退出该怎么办?如果不希望在每一个可能的出口处调用_CrtDumpMemoryLeaks,那么你可以在你的程序开始处包含下面的调用:

_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

  当程序退出时,将会自动地调用_CrtDumpMemoryLeaks(必须设置_CRTDBG_ALLOC_MEM_DF和 _CRTDBG_LEAK_CHECK_DF)。

  翻译内存模块的类型

  内存泄漏报告中把每一块泄漏的内存分为普通块、客户块和CRT块。事实上,你只需要留心普通块和客户块类型。

  普通块(normal block):是由你的程序分配的内存。

  客户块(client block):是一种特殊的内存块,它是由MFC使用的一个对象,程序退出时,该对象的析构函数没有被调用。MFC new操作符可以用来创建普通块和客户块。

  CRT块(CRT block):是由C RunTime Library供自己使用而分配的内存块。CRT库自己来管理这些内存的分配与释放,通常你不会在内存泄漏报告中发现有CRT内存泄漏,除非程序发生了严重的错误(例如CRT库崩溃)。

  下面这两种类型的内存块不会出现在内存泄漏报告中:

   空闲块(free block):已经被释放(free)的内存块。

   忽略块(Ignore block):是程序员显式声明过不要在内存泄漏报告中出现的内存块。
   设置CRT报告样式

  通常_CrtDumpMemoryLeaks()会dump内存泄漏的信息到output窗口的Debug栏位。你可以使用_CrtSetReportMode()来重新设置输出到另一个位置。关于更详细的如何使用_CrtSetReportMode()说明,请查看MSDN。

   在内存分配数目处设置一个断点

  在内存泄漏报告中的文件名和行号可告诉分配泄漏的内存的代码位置,但是光是有这些信息对于完整了解泄漏原因,有时候还是不够的。因为一个程序在运行时,一段分配分配内存的代码将会被调用很多次,但可能是某次调用后没有释放内存而导致了泄漏内存。为了确定是那些内存没有被释放,你必须不仅要知道泄漏的内存在那里被分配,还要知道泄漏产生的条件。对你来说,有帮助的信息就是内存分配号——在文件名和行号之后的花括号对中出现的数值。

  例如,在下面的输出信息中,"18"是内存分配号,意思是泄漏的内存是你程序中分配的第十八个内存块:

Detected memory leaks!
Dumping objects ->
C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18} normal block at
0x00780E80, 64 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:VC 6.0下对配置设置文件的存取访问

下一篇:加密WindowsCE系统

热门词条
热门标签