使用_CRTDBG_LEAK_CHECK_DF检查VC程序的内存泄漏(转)

C/C++内存泄漏与检测 “该死系统存在内存泄漏问题”,项目中由于各方面因素,总是有人抱怨存在内存泄漏,系统长时间运行之后,可用内存越来越少,甚至导致了某些服务失败。内存泄漏是最难发现的常见错误之一,因为除非用完内存或调用malloc失败,否则都不会导致任何问题。实际上,使用C/C++这类没有垃圾回收机制的语言时,你很多时间都花在处理如何正确释放内存上。如果程序运行时间足够长,如后台进程运行在服务器上,只要服务器不宕机就一... 阅读详情

原文链接:http://www.cnblogs.com/qq78292959/archive/2011/05/28/2076605.html


我们知道,MFC程序如果检测到存在内存泄漏,退出程序的时候会在调试窗口提醒内存泄漏。例如:

class CMyApp : public CWinApp
{
public:
BOOL InitApplication()
{
int* leak = new int[10];
return TRUE;
}
};
产生的内存泄漏报告大体如下:

Detected memory leaks!
Dumping objects ->
c:worktest.cpp(186) : {52} normal block at 0x003C4410, 40 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.
这挺好。问题是,如果我们不喜欢MFC,那么难道就没有办法?或者自己做?

呵呵,这不需要。其实,MFC也没有自己做。内存泄漏检测的工作是VC++的C运行库做的。也就是说,只要你是VC++程序员,都可以很方便地检测内存泄漏。我们还是给个样例:

#include

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

void main()
{
EnableMemLeakCheck();
int* leak = new int[10];
}
运行(提醒:不要按Ctrl+F5,按F5),你将发现,产生的内存泄漏报告与MFC类似,但有细节不同,如下:

Detected memory leaks!
Dumping objects ->
{52} normal block at 0x003C4410, 40 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.
为什么呢?看下面。

定位内存泄漏由于哪一句话引起的
你已经发现程序存在内存泄漏。现在的问题是,我们要找泄漏的根源。

一般我们首先确定内存泄漏是由于哪一句引起。在MFC中,这一点很容易。你双击内存泄漏报告的文字,或者在Debug窗口中按F4,IDE就帮你定位到申请该内存块的地方。对于上例,也就是这一句:

int* leak = new int[10];

这多多少少对你分析内存泄漏有点帮助。特别地,如果这个new仅对应一条delete(或者你把delete漏写),这将很快可以确认问题的症结。

我们前面已经看到,不使用MFC的时候,生成的内存泄漏报告与MFC不同,而且你立刻发现按F4不灵。那么难道MFC做了什么手脚?

其实不是,我们来模拟下MFC做的事情。看下例:

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

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

void main()
{
EnableMemLeakCheck();
int* leak = new int[10];
}

再运行这个样例,你惊喜地发现,现在内存泄漏报告和MFC没有任何分别了。

快速找到内存泄漏
单确定了内存泄漏发生在哪一行,有时候并不足够。特别是同一个new对应有多处释放的情形。在实际的工程中,以下两种情况很典型:

创建对象的地方是一个类工厂(ClassFactory)模式。很多甚至全部类实例由同一个new创建。对于此,定位到了new出对象的所在行基本没有多大帮助。

COM对象。我们知道COM对象采用Reference Count维护生命周期。也就是说,对象new的地方只有一个,但是Release的地方很多,你要一个个排除。 
那么,有什么好办法,可以迅速定位内存泄漏?

答:有。

在内存泄漏情况复杂的时候,你可以用以下方法定位内存泄漏。这是我个人认为通用的内存泄漏追踪方法中最有效的手段。

我们再回头看看crtdbg生成的内存泄漏报告:

Detected memory leaks!
Dumping objects ->
c:worktest.cpp(186) : {52} normal block at 0x003C4410, 40 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete. 
除了产生该内存泄漏的内存分配语句所在的文件名、行号为,我们注意到有一个比较陌生的信息:。这个整数值代表了什么意思呢?

其实,它代表了第几次内存分配操作。象这个例子,代表了第52次内存分配操作发生了泄漏。你可能要说,我只new过一次,怎么会是第52次?这很容易理解,其他的内存申请操作在C的初始化过程调用的呗。:)

有没有可能,我们让程序运行到第52次内存分配操作的时候,自动停下来,进入调试状态?所幸,crtdbg确实提供了这样的函数:即 long _CrtSetBreakAlloc(long nAllocID)。我们加上它:

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

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

void main()
{
EnableMemLeakCheck();
_CrtSetBreakAlloc(52);
int* leak = new int[10];
}
你发现,程序运行到 int* leak = new int[10]; 一句时,自动停下来进入调试状态。细细体会一下,你可以发现,这种方式你获得的信息远比在程序退出时获得文件名及行号有价值得多。因为报告泄漏文件名及行号,你获得的只是静态的信息,然而_CrtSetBreakAlloc则是把整个现场恢复,你可以通过对函数调用栈分析(我发现很多人不习惯看函数调用栈,如果你属于这种情况,我强烈推荐你去补上这一课,因为它太重要了)以及其他在线调试技巧,来分析产生内存泄漏的原因。通常情况下,这种分析方法可以在5分钟内找到肇事者。

当然,_CrtSetBreakAlloc要求你的程序执行过程是可还原的(多次执行过程的内存分配顺序不会发生变化)。这个假设在多数情况下成立。不过,在多线程的情况下,这一点有时难以保证。


原文链接:http://www.cnblogs.com/qq78292959/archive/2011/05/28/2076605.html


用_CrtSetBreakAlloc查泄漏 微软提供了在debug模式下查泄漏的方法,主要包括_CrtSetDbgFlag、_CrtDumpMemoryLeaks、_CrtSetBreakAlloc这三个函数 阅读详情

相关推荐

VC/MFC 内存泄漏的个人总结

首先先看看下面的内容吧! 我就是认真阅读了它,并结合自己所学的东西,解决了一个超难得问题(自己觉得!嘿嘿)关于MFC下检查和消除内存泄露的技巧摘要本文分析了Windows环境使用MFC调试内存泄露的技术,介绍了在Windows环境下用VC++查找,定位和消除内存泄露的方法技巧。关键词:VC++;CRT 调试堆函数;试探法。编译环境VC++6.0技术原理检测内存泄漏的主要工具是调试器和 CR

Irene的专栏 3681

最快速度找到内存泄漏

本文已经迁移到:http://cpp.winxgui.com/cn:the-fastest-way-to-find-memory-leak最快速度找到内存泄漏许式伟2006年11月某日 内存管理是C++程序员的痛。我的《内存管理变革》系列就是试图讨论更为有效的内存管理方式,以杜绝(或减少)内存泄漏,减轻C++程序员的负担。由于工作忙的缘故,这个系列目前未完,暂停。   

QBox/Golang/CERL/StdExt/TPL/WinxGui - 许式伟的专栏 2万+

C++中关于Crt的内存泄漏检测的分析介绍

尽管这个概念已经让人说滥了 ,还是想简单记录一下, 以备以后查询。 代码如下:#ifdef _DEBUG#define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)#else#define DEBUG_CLIENTBLOCK#endif#define _CRTDBG_MAP_ALLOC#include #ifdef _DEBUG#define new DEBUG_CLIENTBLOCK#endif int _tmain(int argc, _TCHAR* argv[]){    char* p = n

调试基础:函数 _CrtSetBreakAlloc()使用blog

函数 _CrtSetBreakAlloc(long lBreakAlloc)。 函数说明 MSDN 链接:https://msdn.microsoft.com/en-us/library/4wth1ha5.aspx   在分配块号 lBreakAlloc 的内存时,程序中断。以此来定位内存泄露的大概位置。 注:必须在内存分配之前调用该函数来设置断点。   第一步: 发现有内存泄露:

mrlzl9的博客 1777

别再手动配电脑了!手把手教你用Windows Server 2022搭建企业AD域(附DNS配置避坑指南)

本文详细介绍了如何使用Windows Server 2022搭建企业AD域,提升20+终端的管理效率。通过实战案例和避坑指南,解析AD域的核心价值、部署步骤及DNS配置技巧,帮助企业实现集中权限管理、安全策略统一部署,显著降低IT运维成本。

weixin_30652897的博客 348

【深度强化学习】(2) Double DQN 模型解析,附Pytorch完整代码

Double DQN 算法是 DQN 算法的改进版本,解决了 DQN 算法过估计行为价值的问题。Double DQN 算法不直接通过最大化的方式选取目标网络计算的所有可能 Q 值,而是首先通过估计网络选取最大 Q 值对应的动作。在 Double DQN 框架中存在两个神经网络模型,分别是训练网络与目标网络。这两个神经网络模型的结构完全相同,但是权重参数不同;每训练一段之间后,训练网络的权重参数才会复制给目标网络。

博观而约取,厚积而薄发 1万+

【转载】使用_CRTDBG_LEAK_CHECK_DF检查VC程序的内存泄漏(转)

【转载】http://www.cnblogs.com/qq78292959/archive/2011/05/28/2076605.html 感谢原作者! 我们知道,MFC程序如果检测到存在内存泄漏,退出程序的时候会在调试窗口提醒内存泄漏。例如: class CMyApp : ...

chiaozu5312的博客 103

工程伦理-知识点汇总

工程伦理-知识点汇总

m0_46091747的博客 1万+

使用_CRTDBG_LEAK_CHECK_DF检查VC程序的内存泄漏

  From :http://www.builder.com.cn/2008/0115/708177.shtml我们知道,MFC程序如果检测到存在内存泄漏,退出程序的时候会在调试窗口提醒内存泄漏。例如:class CMyApp : public CWinApp{public:   BOOL InitApplication()   {       int* leak = new in

windows 驱动 反汇编 逆向 1301

光耦继电器电路分析

光耦电路的分析笔记

MingYue_SSS的博客 6873

【重磅更新】CT/MRI LI-RADS 2024:肝细胞癌局部区域治疗后反应评估的核心突破与临床实践指南

减少过度治疗:辐射 LRT 的 Nonprogressing 类别避免了 “持续强化 = 存活” 的误判,降低不必要的再治疗风险;提高检出效率:非辐射 LRT 的辅助特征升级减少了 Equivocal 比例,更早识别存活肿瘤;统一评估语言:标准化的分类标准为放射科、肝病科、肿瘤科、肝移植科的多学科协作(MDT)提供了统一 “沟通工具”,助力治疗方案的精准制定。

楚山之石的博客 1225

VC定位内存泄漏的方法

1、首先查看VC输出的提示信息,例如:      f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {552} normal block at 0x0030C4D0, 44 bytes long.      Data: 3C 4E 46 78 1B 00 00 00 1B 00 00 00 01 00 00 00 

dafenqie的博客 980

声品质粗糙度matlab,声品质的应用分析方法

声品质的应用分析方法2016-04-05 09:18:57阅读次数:14198摘要:声品质分析在噪声的主观评价方面已经得到越来越多的应用。本文比较了声品质分析与传统计权声级的区别,并介绍了在声品质分析的实际应用中,针对稳态信号、非稳态信号的几种不同分析方法,以及各分析方法的要求和特点。关键词:声品质,响度,尖锐度,粗糙度,波动度1前言传统评价噪声的方法主要为计权声压级,用以反映声音的大小。但是人耳...

weixin_30767323的博客 2438

VC添加内存泄露显示信息

#ifdef _DEBUG  _CrtDumpMemoryLeaks();  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif

Keivin 3432

Python二级考试题目及答案解析(含刷题软件)

答案:A 解析:print()函数可以在屏幕上输出指定的字符串或变量,input()函数用于从键盘获取用户输入,int()函数可以将指定的字符串或浮点数转换为整数,float()函数可以将指定的字符串或整数转换为浮点数。答案:A 解析:int()函数可以将字符串转换为整数,float()函数可以将字符串转换为浮点数,str()函数可以将任意类型的变量转换为字符串,bool()函数可以将任意类型的变量转换为布尔值。

YOLO 1万+

UE5 GAS 学习笔记 1.2游戏标签

这一节对GameplayTag游戏标签进行详细的讲解。

CloudHuCoding 1927

Windows下内存泄漏检测方法

Windows下内存泄漏检测方法一1、在主程序的cpp文件里加上以下三行,顺序一定不能颠倒#define _CRTDBG_MAP_ALLOC#include #include 2、在程序退出的时候加上_CrtDumpMemoryLeaks(),如果程序有多个退出的地方,则多个地方

sky101010ws的专栏 3339

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

给VC的控制台程序添加内存泄漏自动检测功能

在VC中,基于MFC框架的应用程序由模板生成时,已经自动添加了内存泄漏自动检测功能。当你的程序有内存泄漏,在Debug调式模式下运行就会在vc的输出窗口里显示出来,非常方便我检查程序漏洞。但是当我写一些测试程序时,往往喜欢用控制台程序来编写,但是控制台程序不会自动添加内存泄漏自动检测功能。我在网上搜索了下,找到了添加的方法,经过我的整理把他写出来,希望对我们都有用!第一步:在程序里定下一下宏(

风神家园 617

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Windows平台下c++ 内存泄漏检查的办法(如VLD)

1. #define CRTDBG_MAP_ALLOC //注意顺序不能乱 #include <stdlib.h> #include <crtdbg.h> int main(void) { int* leak = new int[10]; _CrtDumpMemoryLeaks();//注意必须放在程序的结尾处 return 0; } 2. #include <crtdbg.h> int main(void) { #ifdef...

baidu_16370559的博客 4287

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

上一篇: 图解Window下Telnet与远程桌面登陆工具使用
下一篇: RMI For C++(RCF 1.0)
静水若流深
博客等级 码龄14年 5粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值