使用VLD心得

VLD简介

因为C/C++说话没有所谓的垃圾收集器,内存的分派和开释都须要法度员本身来把握,这会给C/C++法度员带来必然的艰苦。当您的法度越来越错杂时,它的内存经管也会变得越来越艰苦。内存泄漏、内存越界是最常见的内存题目之一。 内存泄漏若是不是很严重的话,在短时候内对法度不会造成太大的影响,并且在过程终止的时辰,所有分派的内存都邑开释掉。然则对于长时候运行的法度,其破损力是惊人的,从机能降落到内存耗尽,甚至会影响到其它法度的正常运行。 此外,内存题目存在一个共同的特点,它本身并不会有很明显的现象,当有异常呈现时就很难检查题目的原因地点,这给调试内存题目带来了很大的难度。 VLD是一款用于VisualC++的免费内存泄漏搜检对象。可以在codeproject.com网站上找到,比拟其它的内存泄漏哦给你按照,他在搜检内存泄漏的同事,还具有如下特点: 1)  可以获得内存泄漏点的调用客栈,若是可以的话,还可以获得其地点的文件及行号; 2)  可以获得泄漏内存的完全数据; 3)  恶意设置内存泄漏呈报的级别; 4)  它以动态库的情势供给,无需编译源代码,只须要很小的批改法度; 5)  源代码应用GNU容许公布,并有具体的文档及其注释。 从应用的角度讲,VLD简单易用,对于应用者本身的代码中独一须要批改的处所是#include VLD的头文件后正常运行本身的法度就可以发明内存题目。从研究角度上讲,若是输入到VLD源代码,可以进修到堆内存分片与开释的道理、内存搜检的道理机械内存操纵的常用技能等。

VLD应用

VLD网址:http://vld.codeplex.com/ http://www.codeproject.com/Articles/9815/Visual-Leak-Detector-Enhanced-Memory-Leak-Detectio Visual LeakDetector,当前版本2.2.3,打开Visual C&#43;&#43; IDE的"对象"→"选项"→"项目和解决规划"→"VC&#43;&#43; 目次",在"包含文件"中增长VLD的头文件路径"include"路径,在"库文件"增长VLD库文件的"libWin32"路径,此外动态库的"inWin32"路径在安装时已经添加到景象变量里面了,若是未添加,则须要手动拷贝"inWin32"下的文件到可履行文件地点的目次中(拷贝的文件有dbghelp.dll/Microsoft.DTfW.DHL.manifest/vld_x86.dll/vld.ini)。 接下来须要将VLD参加到本身的代码中。办法很简单,只要在包含进口函数的.cpp文件中包含vld.h就可以。若是这个cpp文件中包含了stdafx.h,则将包含vld.h的语句放在stdafx.h的包含语句之后,不然放在最前面。 示例法度: #include<vld.h>                 // 包含VLD的头文件 #include<stdlib.h> #include<stdio.h> void f() {     int *p = new int(0 x12345678);     printf("p=%08x, ", p); } int main() {     f();     return 0; } 注:VLD只能在Windows下应用,在包含vld.h头文件时增长预编译选项。 注:在Release模式下,不会链接VisualLeak Detector。 注:Visual LeakDetector有一些设备项,可以设置内存泄漏呈报的保存地(文件、调试器),拷贝"Visual Leak Detector"路径下的vld.ini文件到履行文件地点的目次下(在IDE运行的话,则须要拷贝到目次下),批改以下项: ReportFile =.memory_leak_report.txt ReportTo = both

VLD对象道理

下面我们来看看VLD是如何工作的。在VisualC&#43;&#43;中内置对象CRT Debug Heap对象,在应用Debug版本分配内存时,它会在内存块中记录分派该内存的文件名和行号。当法度退出时CRT会在main函数返回时做一些清理工作,此时搜检调试堆内存,若是仍然有内存没开释,则必然存在内存泄目。从这些没有被开释的内存块的头中可以获得文件名和行号。这种静态的办法可以搜检出内存泄漏,然则不知道泄漏毕竟是怎么产生的,也不知道该内存分派语句是如何被履行到的,想要懂得这些必须对内存分派过程进步履态跟踪。VLD就是如许做的,在每次内存分派的时辰记录其高低文,当法度退出时对检测到的内存泄漏查找其高低文信息,并转换成呈报输出到Output中。

初始化

VLD要记录每次的内存分派,它经由过程Windows供给的分派钩子allocation hooks来把守调试堆内存的分派。它是一个用户自定义的回调函数,在每次从堆平分派内存之前被调用,在初始化是VLD应用_CrtSetAllocation注册这个钩子函数。 全局变量在法度初始化时就初始化,若是将VLD作为一个全局变量就可以与法度一路启动,然则C/C&#43;&#43;并没有商定全局变量初始化的次序,若是其它全局变量的机关函数中有内存分派则可能无法检测到。是以,VLD应用C/C&#43;&#43;供给的#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&#43;&#43;内存泄漏搜检对象,可以在ViusalC&#43;&#43;中应用,在Viusal Studio 2008和2010中应用须要重视两点: 1)  版本题目:VLD已经更新到2.2版本,批改了很多bug,并且在2010版本下工作杰出,VisualC&#43;&#43; 6.0推荐应用1.0版本,1.9b版本不是很稳定不建议应用,2.2版本的网址为http://vld.codeplex.com. 2)  设置变更:VC&#43;&#43;Directories设置已经变更地位,在2010中设置过程如下: View | Other Window | Property Manager Go to "VC&#43;&#43; Directories" settings Set include folder path Set lib folder path 点OK,我们就设置好了include和lib目次。

应用题目

题目1:VLD 1.9

在vista下应用vld的应用,老是呈现错误无常工作,后来经过搜刮,在http://www.codeproject.com/KB/applications/visualleakdetector.aspx 上的评论中找到懂得决的办法: 评论“Solution forrunning 1.9 beta on Visual Studio 2008 with Vista ”给出懂得决办法: 评论1: VLD keptcrashing when trying to use 1.9g beta on Windows Vista, visual studio 2008. Itried all the suggestions on here and nothing worked. But I finally figured itout. when you make a project in visual C&#43;&#43; 2008,it sets some strange advanced Linker properties that cause VLD to crash: I changedLinker->Advanced->Randomized Base Address Enable Image Randomization(/DYNAMICBASE) to Disable Image Randomization (/DYNAMICBASE:NO) Then I changed Linker->Advanced->Dataution Prevention Image is compatible with DEP (/NXCOMPAT) to Default And now it works perfectly Please let me know if this helped you!It""ll make me feel better for spending a whole day trying to get it working!  -Nadav 评论2: The base address randomization seems to benot necessary. Just disable DEP. 大致的意思是说,只须要禁用DEP即可, 在的“属性”->“链接器”->“高等”->数据履行保护(DEP),设为“默认”(default)或者“映像与 DEP 不兼容(/NXCOMPAT:NO)“ 即可。(批改后如同不成用)。 注:这个选项只针对Vista有效!!!

题目2:VLD 2.2.3

在项目中应用了visual leak detector,调试时法度无法启动报错“应用法度正常启动失败(0 xc0150002)”。 解决流程: 查看vs输出信息最后一条是: Theprogram ""[3980] MobileSignalAnalyzer.exe: Native"" has exited with code-1072365566 (0 xc0150002) 在网上多方查找有: http://blog.csdn.net/evilswords/article/details/5698851 http://blog.csdn.net/brook0344/article/details/6685724 这两篇有解决办法,就是把VLD中的这两个复制到履行文件夹下就正常了 Microsoft.VC90.CRT.manifest Microsoft.DTfW.DHL.manifest 产生原因: VC2003、VC2005、VC2008及厥后续版本,对底层最根蒂根基的CRT、MFC、ATL库都进行了重构,为了避免不合版本的库引起冲突,重构后的库文件一般放在C://windows/WinSxS 文件夹中,并用特定的文件夹/文件名称进行标识; 与VC6不合, VC2003、VC2005、VC2008及厥后续版本,引入了manifest清单的概念,即应用法度编译后会同时生成对应的.manifest文件,

你可能感兴趣的:(使用VLD心得)