内存泄露检测(待补充)

    内存泄露,即在程序中动态分配的堆内存,没有得到释放,导致可用的堆内存越来越少,造成程序性能下降,严重者导致程序崩溃。C/C++不像Java那样有内存自动回收自制,C/C++的设计哲学就是程序员要对自己所担当的一切负责任,自由的内存分配带来了编程的灵活性,让程序员直接操作内存,程序效率更高。即使看似无害的内存泄露也要及时修正,因为对于一些长时间运行的系统或者一些长时间的后台程序,极微小的内存泄露也可能造成系统的奔溃。编程是一个很严谨的事情。

    Visual Studio和c运行库(CRT)提供了检测内存泄露的方法。

启用CRT中的内存泄露检测机制

    首先,来看一个程序:

<span style="font-family:SimSun;font-size:14px;">#include "stdafx.h"

</span><pre name="code" class="html"><span style="font-family:SimSun;font-size:14px;">#define _CRTDBG_MAP_ALLOC</span>
#define _DEBUG#include "stdlib.h"#include "crtdbg.h"#ifdef _DEBUG#ifndef DBG_NEW#define DBG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)#define new DBG_NEW#endif#endifvoid fun(){int *p = (int *)malloc(sizeof(int) * 10);}void main(){_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

 
<span style="font-family:SimSun;font-size:14px;"><span style="white-space:pre">	</span>fun();

	//int *nPtr = new int[10];
}</span>


用VS编译运行结束后(按F5直接运行,不要按Ctrl + F5),出现如下结果:

<span style="font-family:SimSun;font-size:14px;">Detected memory leaks!
Dumping objects ->
c:\users\wyp\documents\visual studio 2008\projects\2014101502\2014101502\2014101502.cpp(33) : {63} normal block at 0x01263CC8, 40 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.</span>

为了启用CRT的内存泄露检测机制,需要以下操作:

<span style="font-family:SimSun;font-size:14px;">#define _CRTDBG_MAP_ALLOC
#include "crtdbg.h"</span>
crtdbg.h:将malloc和free或new和delete映射到它们的调试版本,它们的调试版本将跟踪内存的分配和释放。此映射只在包含_DEBUG的调试版本中有用,Release版本使用效率高一些的malloc和free或new和delete

_CRTDBG_MAP_ALLOC:将CRT堆函数的基础版本映射到对应的调试版本。省略_CRTDBG_MAP_ALLOC宏,内存泄露转储将有所简化。


内存泄露检测机制启用后,就可以使用_CrtDumpMemoryLeaks()函数在程序退出时显示内存泄露报告,该函数设置在应用程序的退出点之前,如果应用程序有多个退出点,不需要再每个退出点都手动设置一个对_CrtDumpMemoryLeaks()的调用。在应用程序开头部分使用_CrtSetDbgFlag函数设置flag就会导致在程序的每个退出点自动调用_CrtDumpMemoryLeaks函数。同时,必须设置两个标志:

<span style="font-family:SimSun;font-size:14px;">_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);</span>

内存泄露报告详解

如果应用程序未定义_CRTDBG_MAP_ALLOC,则_CrtDumpMemoryLeaks显示的内存泄露报告如下:

<span style="font-family:SimSun;font-size:14px;">Detected memory leaks!
Dumping objects ->
{63} normal block at 0x01163CC8, 40 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.</span>

如果应用程序定义了_CRTDBG_MAP_ALLOC,则_CrtDumpMemoryLeaks显示的内存泄露报告如下:

<span style="font-family:SimSun;font-size:14px;">Detected memory leaks!
Dumping objects ->
c:\users\wyp\documents\visual studio 2008\projects\2014101502\2014101502\2014101502.cpp(33) : {63} normal block at 0x01263CC8, 40 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.</span>

区别在于,第二份报告显示文件名,以及泄漏的内存初次分配所在位置的行号。

不论是否定义 _CRTDBG_MAP_ALLOC,内存泄漏报告都显示以下信息:

  • 内存分配编号,在本例中为 18

  • 块类型,在本例中为 normal

  • 十六进制内存位置,在本例中为 0x00780E80

  • 块的大小,在本例中为 64 bytes

  • 块中前 16 个字节的数据(十六进制形式)。

内存泄漏报告将内存块标识为普通、客户端或 CRT。 “普通块”是由程序分配的普通内存。 “客户端块”是由 MFC 程序用于需要析构函数的对象的特殊类型内存块。MFC new 运算符根据正在创建的对象的需要创建普通块或客户端块。 “CRT 块”是由 CRT 库为自己使用而分配的内存块。 CRT 库可处理这些块的释放。 因此,您不大可能在内存泄漏报告中看到这些块,除非出现严重错误(例如 CRT 库损坏)。

内存泄漏报告中绝对不会出现另外两个内存块类型。 “可用块”是已释放的内存。 也就是说,根据定义,这种块不会泄漏。 “忽略块”是已明确标记、不出现在内存泄漏报告中的块。

这些方法适用于使用标准 CRT malloc 函数分配的内存。 不过,如果程序使用 C++ new 运算符分配内存,则需要重新定义 new 才能在内存泄漏报告中看到文件和行号。 您可以利用如下所示的代码块实现:

#ifdef _DEBUG
   #ifndef DBG_NEW
      #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
      #define new DBG_NEW
   #endif
#endif  // _DEBUG

参考资料:

http://blog.csdn.net/genganpeng/article/details/7558156

http://blog.csdn.net/normallife/article/details/3278659




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值