VLD(Visual LeakDetector)内存泄露检测(QT+VS2015+VLD2.5.1)

1. 原理:

这篇文章讲清楚了:

https://wenku.baidu.com/view/543cd4e8e87101f69f31956c.html

 

VLD工具原理

下面我们来看看VLD是如何工作的。在VisualC++中内置工具CRT Debug Heap工具,在使用Debug版本分配内存时,它会在内存块中记录分配该内存的文件名和行号。当程序退出时CRT会在main函数返回时做一些清理工作,此时检查调试堆内存,如果仍然有内存没释放,则一定存在内存泄漏问题。从这些没有被释放的内存块的头中可以得到文件名和行号。这种静态的方法可以检查出内存泄漏,但是不知道泄漏究竟是怎么发生的,也不知道该内存分配语句是如何被执行到的,想要了解这些必须对内存分配过程进行动态跟踪。VLD就是这样做的,在每次内存分配的时候记录其上下文,当程序退出时对检测到的内存泄漏查找其上下文信息,并转换成报告输出到Output中。

 相比较其它内存泄露检测工具,它在检测到内存泄漏的同时,还具有如下特点:

   1. 可以得到内存泄漏点的调用堆栈,如果可以的话,还能得到其所在文件及行号;
    2.可以得到泄露内存的完整数据;
   3.  可以设置内存泄露报告的级别;
    4. 它是一个已经打包的 lib,使用时无须编译源码。对于使用者自己的代码,只需要做很小的改动;
    5. 源码使用 GNU 许可发布,并有详尽的文档及注释。对于想深入了解堆内存管理的读者,是一个不错的选择。
 

初始化

VLD要记录每次的内存分配,它通过Windows提供的分配钩子allocation hooks来监视调试堆内存的分配。它是一个用户自定义的回调函数,在每次从堆中分配内存之前被调用,在初始化是VLD使用_CrtSetAllocation注册这个钩子函数。全局变量在程序初始化时就初始化,如果将VLD作为一个全局变量就可以与程序一起启动,但是C/C++并没有约定全局变量初始化的顺序,如果其它全局变量的构造函数中有内存分配则可能无法检测到。因此,VLD使用C/C++提供的#pragma init_seg来减少其它全局变量在它之前进行初始化。根据#pragma init_seg的定义,全局变量初始化分为3个阶段,首先是compiler阶段,一般进行C语言运行时库的初始化;然后是lib段,一般用于第三方类库的初始化扽;最后是user段,大部分的初始化都在这个阶段进行。

记录内存分配

一个内存分配钩子函数需要具有如下的定义:int AllocHook(int allocType, void*userData, size_t size,int blockType, long requestNumber, onst unsigned char*filename, int lineNumber); 该函数需要在VLD初始化时被注册,每次从堆中分配内存前被调用,它需要处理的事情就是记录下此时的调用堆栈和此时堆内存分配的唯一标识requestNumber。得到当前堆栈的二进制表示并不是很复杂的事情,但是因为不同的体系结构、不同的编译器、不同的操作系统所产生的堆栈内容是不一样的,要解释堆栈并得到整个函数的调用过程比较复杂。不过Windows提供了一个StackWalk64函数可以获得堆栈的内容。 VLD是常用的C/C++内存泄漏检查工具,可以在ViusalC++中使用,在Viusal Studio 2008和2010中使用需要注意两点: 1)  版本问题:VLD已经更新到2.2版本,修正了许多bug,而且在2010版本下工作良好,VisualC++ 6.0推荐使用1.0版本,1.9b版本不是很稳定不建议使用,2.2版本的下载网址为http://vld.codeplex.com. 2)  设置变化:VC++Directories设置已经变化位置,在2010中设置过程如下:View | Other Window | Property ManagerGo to "VC++ Directories" settingsSet include folder pathSet lib folder path 点OK,我们就设置好了include和lib目录。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值