Windows平台下c++ 内存泄漏检查的办法(如VLD)
1. VC自带的CRT:_CrtCheckMemory 调试器和 CRT 调试堆函数
主要适用于:win32,在mfc平台直接使用AfxDumpMemoryLeaks。不需要引用头文件和define任何东西
该函数只在Debug版本才有用,当在调试器下运行程序时,_CrtDumpMemoryLeaks 将在“Output(输出)”窗口中显示内存泄漏信息。但是这个函数只能输出是否有内存泄漏,并不能定位到哪里出现了内存泄漏,因此我们需要参考mfc的方式来加入文件名称和代码行号。
一是包含调试堆函数库文件:
#include<crtdbg.h>
二是在需要检测内存泄漏的地方添加下面这条语句来输出内存泄漏信息:
_CrtDumpMemoryLeaks();
最好在代码中增加
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
宏定义,可以输出内存泄漏具体的文件位置信息。
#include<crtdbg.h>
#ifdef _DEBUG
#define new new( _NORMAL_BLOCK, __FILE__, __LINE__)
#endif
int main()
{
int* p = new int[10];
_CrtDumpMemoryLeaks();
return 0;
}
注意:如果程序总是在同一位置退出,调用 _CrtDumpMemoryLeaks 将非常容易。 如果程序从多个位置退出,则无需在每个可能退出的位置放置对_CrtDumpMemoryLeaks 的调用,而可以在程序开始处包含以下调用:
1 |
|
该语句在程序退出时自动调用 _CrtDumpMemoryLeaks。 必须同时设置 _CRTDBG_ALLOC_MEM_DF 和 _CRTDBG_LEAK_CHECK_DF 两个位域。
2.使用Visual Leak Detector(VLD)
VLD的最新版本为2.5.1,下载地址: VLD2.5.1。这个是别人弄好的下载。
或者使用该链接: https://pan.baidu.com/s/12GUr8MhUEzSO1YYTTS4Edg 提取码: 6rgj
下载到的软件是:vld-2.5.1-setup.exe 。安装后,其安装目录为:
也可以到官网下载,下载地址为:https://kinddragon.github.io/vld/
配置VLD
打开VS2017,创建一个新工程,在资源管理器中项目右键,点击属性,进入项目属性页进行配置,用这种方法配置只能在本项目中使用VLD。若想一劳永逸,使所有项目都能使用VLD,则需要从属性管理器中进入“Microsoft.Cpp.x64.user”属性页(64位)或者“Microsoft.Cpp.Win32.user”属性页(32位)。本文从项目属性页对其进行配置。
设置 配置属性->VC++目录->包含目录:安装目录\include
设置 配置属性->VC++目录->库目录:安装目录\lib
注意事项:
1.不需要在链接器->输入->附加依赖项中添加xx.lib 文件
2.也不需要把dll放在运行目录下
如果是在安装exe时,选择把vld安转到vs环境中,会自动为项目设置继承,不需要再手动添加include和lib文件了,相当于跳过这一步。
定位显示行号
配置属性->链接器->所有选项->生成调试信息 选择“生成经过优化以共享和发布的调试信息(/DEBUG:FULL)”,然后点击确定
另外还有一种办法显示行号:没测试过
需要更新dbghelp.dll,具体方法为:将VS2017 的dbghelp放到VLD里,替换VLD目录下的dbhelp.dll
VS2017 的dbghelp的路径为:
%programfiles(x86)%\Microsoft Visual Studio\2017\版本类型\Common7\IDE\CommonExtensions\Microsoft\TestWindow\Extensions\Cpp
添加头文件
如果是没有预编译头,直接在main函数所在的cpp最前面加上#include "vld.h",
若是有预编译头且是mfc程序,这最好在预编译头里#include <afxwin.h>前加上#include "vld.h"
如即一般放在stdafx.h或者pch.h文件前面位置。也就满足 如果有include"stdafx.h",则#include "vld.h"放在其后,否则放在最前面。
这个时候如果代码路径里没有中文,应该就可以正常使用了。但是如果有中文的话可能会出现:无法显示Call Stack文,得不到具体泄露的位置的问题。解决方法为:编辑VLD安装目录下的配置文件vld.ini,将ReportEncoding = ascii改为ReportEncoding = unicode就可以了。
测试现象和结果
同时默认的情况下,会在源码工程目录下生成memory_leak_report.txt报告
如果有了调试信息,但在源码工程目录下没看到memory_leak_report.txt。是因为vld.ini 文件缺省配置为ReportTo = debugger 。应该改成ReportTo = both。
如果同时exe和多个dll,需要在每个exe和dll都要#include "vld.h",这样才能有内存泄漏日志产生。
如果只设置dll有#include "vld.h",并且产生了内存泄漏日志,则日志保存在dll的源码工程下,否则在exe的源码工程下。
注意事项:
1 如果有include"stdafx.h",则include <vld.h>放在其后,否则放在最前面
2 VLD只在debug版本有效
3 如果想将产生的日志保存到文件中,需要将vld.ini(VLD安装目录下)复制到可执行文件目录下,
然后作如下修改:
ReportFile =.\memory_leak_report.txt
ReportTo = both //设置为both,才能会在源码工程目录下生成报告
4.但是只支持MSVC编译器,不支持MingGW编译器。
原理:
在VisualC++中内置工具CRT Debug Heap工具,在使用Debug版本分配内存时,它会在内存块中记录分配该内存的文件名和行号。当程序退出时CRT会在main函数返回时做一些清理工作,此时检查调试堆内存,如果仍然有内存没释放,则一定存在内存泄漏问题。从这些没有被释放的内存块的头中可以得到文件名和行号。这种静态的方法可以检查出内存泄漏,但是不知道泄漏究竟是怎么发生的,也不知道该内存分配语句是如何被执行到的,想要了解这些必须对内存分配过程进行动态跟踪。VLD就是这样做的,在每次内存分配的时候记录其上下文,当程序退出时对检测到的内存泄漏查找其上下文信息,并转换成报告输出到Output中
Visual Leak Detector的工作分为3步,
1)首先在初始化注册一个钩子函数;
2)然后在内存分配时该钩子函数被调用以记录下当时的现场;
3)最后检查堆内存分配链表以确定是 否存在内存泄漏并将泄漏内存的现场转换成可读的形式输出。
3.VS2017的Debug下的诊断工具
简单的程序可以实现记录快照和对比查找泄露位置,但是复杂的程序快照记录没问题,不过对比快照的时候会出现卡住的情况
4.神器:VS2017性能探查器的内存使用率分析(ALT+F2或者菜单调试->性能探查器)
可以做快照对比,能支持Debug和Release,使用后感觉应该是目前我用过最方便直观的内存泄露检测工具。
Windows平台下c++ 内存泄漏检查的办法(如VLD)相关推荐
- Windows平台下的内存泄漏检测
Windows平台下的内存泄漏检测 一.使用_CrtDumpMemoryLeaks定位内存泄露 添加对应的头文件 转储内存泄漏信息 程序任意点退出 指定调试信息输出 二.定位具体内存泄露位置 内存快照 ...
- Windows平台下的SOCKS5代理配置与网络安全
本文将介绍在Windows平台下配置SOCKS5代理的方法,并探讨该代理协议在网络安全中的应用.通过正确配置SOCKS5代理,用户可以提高网络连接的安全性和隐私保护. 在当今信息时代,网络安全问题备受 ...
- windows平台下vlc编译之十三:vlc1.1.0编译
请移步https://higoge.github.io/,所有下载资料在那个博客都能找到.谢谢. --------------------------------------------------- ...
- windows平台下vlc编译之六:vlc-0.9.8a的编译
请移步https://higoge.github.io/,所有下载资料在那个博客都能找到.谢谢. --------------------------------------------------- ...
- Windows平台下Makefile学习笔记
来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译平台的问题(发现一些开源代码已经在使用VS2010开发,但我还没安 ...
- windows平台下vlc编译
转自:http://jeremiah.blog.51cto.com/539865/114190 Jeremiah刚刚工作几个月,参与的第一个项目是与视频监控有关,分配给我的任务就是用开源的vl ...
- Linux 下几款程序内存泄漏检查工具
Linux 下几款程序内存泄漏检查工具 chenyoubing | 发布于 2016-07-23 10:08:09 | 阅读量 93 | 无 写这篇博客的原因呢是因为自己在编写基于Nginx磁盘缓存管 ...
- Windows平台下Git服务器搭建
初识Git Git是什么? Git是目前世界上最先进的分布式版本控制系统. SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑, ...
- linux c 代码分析工具,编程达人 分享几款Linux 下C/C++程序内存泄漏检查工具
1.内存管理是否正确(因为这个程序本身开辟很多内存空间进行缓存管理,同时这个程序程序本身就是基于C/C++开发的,内存管理机制一直是程序员头痛的东西) 2.程序的健硕性如何(服务器任何程序的基本要求就 ...
- Windows平台下的session0创建进程的问题与解决办法
Windows平台下的session0创建进程的问题与解决办法 参考文章: (1)Windows平台下的session0创建进程的问题与解决办法 (2)https://www.cnblogs.com/ ...
最新文章
- LeetCode简单题之判断字符串的两半是否相似
- Intel Optane(tm) Memory Pinning 无法加载DLLiaStorAfsServiceApi.dll:找不到指定模块。(异常来自HRESULT:0x8007007E)。
- asp.net 2中的图片上传
- P3577-[POI2014]TUR-Tourism【状压dp】
- python查看电脑配置_怎么查看电脑配置(教你如何查看电脑配置信息和型号)
- DeleteDC、ReleaseDC、DeleteObject - [Daliy APIs]
- 【开发经验】fiddler实现请求转发
- 数据库设计-简化字典表
- c语言实现矩阵转置、矩阵乘法
- Linux下使用和配置magick
- android如何保证多线程安全,保证线程安全的方式有哪几种?
- (转贴)联想员工亲历联想大裁员:公司不是家
- Report Builder简单的使用操作
- 微信去除 防欺诈或盗号请不要输入qq密码 的方法
- 程序员面试智力题(六)
- verilog中define、parameter、localparam的区别
- 金字塔原理4个基本原则_总结盆景养护的4个原则
- 集成学习_GBDT_XGBoost
- 阿里大佬2019年回顾:有他60%的努力,何愁进不了大公司
- [HEOI2012]采花
热门文章
- nodejs之路-[0]安装及简易配置
- 资源 | 有了这些字体,你的设计也立即“高大上”起来。
- 如何去掉word中的回车符??
- Hibernate在自由状态和持久的状态转变
- 18th, Oct 端正心态,积蓄实力,等待爆发的一刻
- phpmailer thinkphp3.2发送邮件
- Bootstrap3的简单入门
- winfrom模拟表单同步数据、上传文件(.net core)
- 服务器系列和酷睿系列,三大系列 从英特尔主流处理器选择服务器(2)
- PHP如果某商品下的所有货品库存都为0,则下架该商品