VC++ 内存泄露与检测的一种方法
本文介绍,当VC++或者MFC程序,出现内存泄露时,如何快速定位的方法,这种方法有一定的局限性,在注意事项中会给出的。
MFC程序
当MFC程序出现内存泄露时,退出程序时的VS调试输出窗口,一般会有如下显示:
上面显示了在程序的哪个文件的哪行语句,发生了内存泄露,其中:
{345}: 表示 内存分配编号
normal block:表示 内存块类型,有普通块(普通程序分配)、客户端块(分配基于CObject的内存)和CRT块(库函数内部分配)这几种类型
0x0074A030:以16进制形式输出的内存位置
40 bytes long: 以字节为单位的内存块大小
Data< >CD CD ..:内存块前16个字节的内容,16进制表示。
定位内存泄露位置,可以双击泄露信息,也可以在输出窗口 按F4键,跳转到 出错行。
普通VC++程序
在普通VC++程序中,要类似MFC中内存检测的效果,需要做如下操作。
1. 在头文件中,添加 #include <ctrdbg.h>
2. 在程序入口最开始处,添加 下面两句话即可
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); //设置调试堆函数跟踪分配的方式
//_CrtSetBreakAlloc(); //这句话,在确实有内存泄露的情况下,给 内存分配编号
3. 按F5,运行程序,等待程序退出后,在输出窗口可以看到下面的情况:
如图所示,程序有两处内存泄露地方,分配编号为 476 和 475,此时,给_CrtSetBreakAlloc()函数传入476参数,再次运行程序,在退出时,会弹出如下窗口:
点击 中断 跳到,_CrtSetBreakAlloc()中断的地方,然后在程序中,通过查看调用堆栈,就可以看到应用程序的哪一次new操作没有执行delete操作。
在中断的同时,也可以从控制台中,看到整个程序析构的顺序,如下图所示:
注意事项
1. 当程序确认没有内存泄露时,不可以调用_CrtSetBreakAlloc(475),因为,这样会在指定内存分配次数发生时,强制中断程序。
2. 这种检测内存分配的方式,要求,程序在执行过程中,是可还原的(多次执行过程的内存分配顺序不会发送变化),这个假设,在多数情况下是成立的,不过,在多线程执行的环境下,有时候难以保证。
3. 对于普通C程序,上述检测方法也是成立的,只不过new换成了malloc,delete换成了free
4. 比如 int *p = new int[4]; delete p; 这种方式的泄露,上述方法是检测不出来,此时,需要cppcheck等更有力的工具来检查。
参考链接:C++调试堆
VC++ 内存泄露与检测的一种方法的更多相关文章
- CPP-基础:内存泄露及其检测工具
[转]浅谈C/C++内存泄露及其检测工具 对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题.已经有许多技术被研究出来以应对这个问题,比如 Smart Pointer,Garba ...
- [转]浅谈C/C++内存泄露及其检测工具
转自:http://www.cnblogs.com/taoxu0903/archive/2007/10/27/939261.html 对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问 ...
- C/C++内存泄露及检测工具
内存泄漏的定义 一般我们常说的内存泄漏是指堆内存的泄漏.堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显示释放的内 存.应用程序一般使用malloc,re ...
- C++中内存泄露的检测
C++没有java的内存垃圾回收机制,在程序短的时候可能比较容易发现问题,在程序长的时候是否有什么检测的方法呢? 假设有一个函数可以某点检测程序的内存使用情况,那是否可以在程序开始的时候设置一个点,在 ...
- Windows系统中内存泄露与检测工具及方法
1.检测需要使用的工具:windbg工具.检测前,需要先安装windbg工具.安装了该工具后,会在安装目录下有一个umdh工具.假设windbg安装在以下目录下:D:\Program Files\De ...
- Android内存泄露自动检测神器LeakCanary
经典的面试题: a.怎样在coding过程中避免内存泄露? b.怎样检测内存泄露? 这两个问题我想大部分Android 职位面试时都会被问到吧. 怎样避免就不赘述了,网上很多答案. 工具呢,当然也有很 ...
- c/c++内存泄露的检测方法
此文内容摘自 https://zhuanlan.zhihu.com/p/22664202 作为 从零开始的 JSON 库教程(三):解析字符串解答篇 的笔记 1A. Windows 下的内存泄漏 ...
- jenkins的sonarqube之代码检测的两种方法
#:sonarqube下载地址,我们安装6.7 高版本已经不支持MySQL和Mariadb(最小3G内存) https://www.sonarqube.org/downloads/ #:安装文档 h ...
- VC启动一个新线程的三种方法
第一种AfxBeginThread() 用AfxBeginThread()函数来创建一个新线程来执行任务,工作者线程的AfxBeginThread的原型如下: CWinThread* AfxBegin ...
随机推荐
- Faiss教程:GPU
Fassi通过CUDA支持GPU,要求3.5以上算力,float16要求CUDA7.5+ 通过index_gpu_to_cpu可以将索引从GPU复制到CPU,index_cpu_to_gpu 和 in ...
- go语言可变参数的坑
0x00 前提 对可变参数不了解的同学,可以先看这篇文章可变参数终极指南 0x01 第一个坑 不能通过空接口类型向可变参数传递一个普通的切片 ,需要将普通切片转换为空接口切片 0x02 第二个坑 可变 ...
- java基础篇---Servlet过滤器
Servlet过滤器从字面上的字意理解为景观一层次的过滤处理才达到使用的要求,而其实Servlet过滤器就是服务器与客户端请求与响应的中间层组件,在实际项目开发中Servlet过滤器主要用于对浏览器的 ...
- 如何通过Dreamweaver批量对整个站点或目录进行代码搜索或部分全部替换
原文地址:http://www.idc523.com/faq/view-331.html 如何通过Dreamweaver批量对整个站点或目录进行代码搜索或部分全部替换 有的时候,我们希望修改网站代码或 ...
- Eval与DataBinder.Eval的区别
DataBinder.Eval的基本格式 DataBinder.Eval(Container.DataItem,"XXX","{0}") <%# Data ...
- git commit 合并
日常 git 管理代码的时候,经常因为因为一些小的代码改动而进行一次 git commit , 但是这样造成的后果就是小的 git commit 很多很杂. 今天特意的研究了一些 git commit ...
- [培训]keysight培训
DDR DDR->DDR2->DDR3->DDR4->DDR5->HBM, LPDDR(low power DDR)
- Android ——利用OnDraw实现自定义View(转)
自定义View的实现方式大概可以分为三种,自绘控件.组合控件.以及继承控件.本文将介绍自绘控件的用法.自绘控件的意思是,这个控件上的内容是用onDraw函数绘制出来的.关于onDraw函数的介绍可参看 ...
- [算法]和为S的连续正数序列
题目描述 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久,他 ...
- Spring,hibernate,struts的面试笔试题(含答案)
Hibernate工作原理及为什么要用? 原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3.打开Sesssion 4.创建事务Transation 5.持久 ...