c/c++的内存泄露查找 _CrtSetDbgFlag()

此文章针对控制台与win32项目

我以Windows下visual studio为例解释步骤

1.在stdafx.h头文件中添加以下代码

#include <crtdbg.h>

#ifdef _DEBUG
#define DEBUG_NEW   new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_NEW
#endif

#define _CRTDBG_MAP_ALLOC

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

 

2.当然你也可以将上面的内容缩减为下面这样:

#include<crtdbg.h>

#ifdef _DEBUG

#define new new(_CLIENT_BLOCK, __FILE__, __LINE__)

#define _CRTDBG_MAP_ALLOC

 

3.要使用vc提供的内存泄露查找功能还需要在你的入口点函数中添加下面这句

_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF) ;

以下贴出msdn对以上两个标志的解释:

_CRTDBG_ALLOC_MEM_DF

ON: Enable debug heap allocations and use of memory block type identifiers, such as_CLIENT_BLOCK. OFF: Add new allocations to heap's linked list, but set block type to_IGNORE_BLOCK.

Can also be combined with any of the heap-frequency check macros.

_CRTDBG_LEAK_CHECK_DF

ON: Perform automatic leak checking at program exit through a call to _CrtDumpMemoryLeaks and generate an error report if the application failed to free all the memory it allocated. OFF: Do not automatically perform leak checking at program exit.

Can also be combined with any of the heap-frequency check macros.

 

4.对上面的内容做些简单解释

上面对new的宏扩展与_CRTDBG_MAP_ALLOC的定义分别是为了使用调试模式的new与malloc。

调试模式下的new与malloc可以定位内存泄露的文件名与行号,便于查找调试。

 

(1).经过扩展后,new调用的就变为dbgnew.cpp文件中的下面这个函数

void *__CRTDECL operator new(
        size_t cb,
        int nBlockUse,
        const char * szFileName,
        int nLine
        )
        _THROW1(_STD bad_alloc)

这样当你调用new int ;的时候实际上就是调用了new(_CLIENT_BLOCK, __FILE__, __LINE__) int ;即对应于上面的那个函数。

这种new的语法形式好像和普通的重载不太一样。嗯,我也不太懂,这大概是new的特殊方式吧。。。望高人指点

这里再说一下_CLIENT_BLOCK,这个是内存块类型。有以下几种:

/* Memory block identification */
#define _FREE_BLOCK      0
#define _NORMAL_BLOCK    1
#define _CRT_BLOCK       2
#define _IGNORE_BLOCK    3
#define _CLIENT_BLOCK    4
#define _MAX_BLOCKS      5

详见:http://msdn.microsoft.com/zh-cn/library/htdyz80k.aspx

(2).当你调用malloc时,就直接调用下面函数了:

extern "C" _CRTIMP void * __cdecl _malloc_dbg (
        size_t nSize,
        int nBlockUse,
        const char * szFileName,
        int nLine
        )

该函数位于dbgheap.c中

这次是因为定义了_CRTDBG_MAP_ALLOC这个常量后,在crtdbg.h文件中有一个宏扩展。如下图:

 

5.最后有可能在编译时出现警告,如下图:

这个原因编译器写的很清楚了,所以我们能做的就是根据自己的需要注释掉会产生问题的文件

举例:想在调试模式检查内存泄露,可以选择注释掉malloc.h文件

           不想检测malloc产生的内存泄露位置,可以选择注释掉_CRTDBG_MAP_ALLOC这个常量定义

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值