有关内存泄露检测的一些知识。

在练习智能指针代码实现双链表的时候,由于担心引发循环引用,导致内存泄露,所以在测试的文件中加入了检测内存泄露的一些语句。作为了解,在这里也简单的说一下有关内存泄露检测的一些方法。其中参考了msdn的一些内容

首先说明,如果想要启用内存泄露检测,需要包含头文件:crtdbg.h

如果只是想简单的了解到底内存是否泄露,可以在包含了头文件crtdbg.h文件之后。在程序即将结束退出之前加入下面的函数:

_CrtDumpMemoryLeaks();

那么在调试器状态下,如果发生了内存的泄露,在输出(调试信息)栏里面就会出现:

Detected memory leaks!
Dumping objects ->{18}normal block at 0x0070FFE0, 64 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

如果程序存在多个出口,我们当然不必在每个出口都加上_CrtDumpMemoryLeaks()。根据msdn中描述的如下:检测内存泄漏的主要工具是调试器和 C 运行时库 (CRT) 调试堆函数。若要启用调试堆函数,请在程序中包括以下语句:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include  语句必须采用上文所示顺序。如果更改了顺序,所使用的函数可能无法正确工作。通过包括 crtdbg.h,将 malloc 和 free 函数映射到其“Debug”版本 _malloc_dbg 和 _free_dbg,这些函数将跟踪内存分配和释放。


当然我们写程序到达这里肯定是不甘心的,如果我们的代码中出现了内存泄露,我们当然想要知道问题到底出现在哪里。

我在网上查了不少的资料,其中在刚刚的MSDN中介绍,如果要显示这样的效果:

Detected memory leaks!
Dumping objects ->
c:\projects\test.cpp(26) : {137} normal block at 
0x00848A28, 4 bytes long.
 Data: <    > 06 00 00 00 
Object dump complete.

msdn上介绍说,需要在程序的开始加上下面的语句:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

但是经过测试发现这不能实现,可能是老版本的实现吧。

后来google了一下发现了新的方法,但是看上去好像有些繁琐。贴上我的测试的文件:

#ifdef _DEBUG
#define MYDEBUG_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 MYDEBUG_NEW
#endif // _DEBUG
#ifdef _DEBUG
#define new MYDEBUG_NEW
#endif

#include <iostream>
#include <crtdbg.h>
int main(){{int* a = new int(6);}_CrtDumpMemoryLeaks();return 0;}

在程序的最上头,加上这么一些宏定义就可以实现如下效果:

Detected memory leaks!
Dumping objects ->
c:\users\jmy\documents\visual studio 2012\projects\test\test.cpp(19) : {137} normal block at 0x00858858, 4 bytes long.
 Data: <    > 06 00 00 00 
Object dump complete.

显示出了代码所在的文件,和代码所在文件的行数。

还有另外的一种形式,设置程序的断点,_CrtSetBreakAlloc(long number);其中的number就是上面在程序泄露的时候,分配内存的次数,即第几次分配内存。

如,上图中的{137}就是应该的number值。 

#include <crtdbg.h>

inline void EnableMemLeakCheck()
{
	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
}

int main()
{

	EnableMemLeakCheck();
	_CrtSetBreakAlloc(137);

	int* a = new int(8);
	_CrtDumpMemoryLeaks();

	return 0;
}

通过上面的调用,当程序执行到哪个内存分配的时候,断点就会停在那里。也可以起到找到问题代码所在行的目的。

暂时先更新到这里,有问题大家再提。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值