
C/C++ 程序越复杂,内存的管理显得越重要,稍有不慎就会出现泄漏。如果内存泄漏不是很严重,在短时间内对程序不会有太大影响,这也使得内存泄漏问题有很强的隐蔽性,不易被发现。然而不管内存泄漏多么轻微,当程序长时间运行时,其破坏力是惊人的 - 从性能下降到内存耗尽,甚至会影响其他程序的正常运行。
VLD
VLD(Visual Leak Detector)是一款用于 Visual C++ 的免费内存泄露检测工具。
相比较其它内存泄露检测工具,它在检测到内存泄漏的同时,还具有如下特点:
- 可以得到内存泄漏点的调用堆栈,如果可以的话,还能得到其所在文件及行号;
- 可以得到泄露内存的完整数据;
- 可以设置内存泄露报告的级别;
- 它是一个已经打包的 lib,使用时无须编译源码。对于使用者自己的代码,只需要做很小的改动;
- 源码使用 GNU 许可发布,并有详尽的文档及注释。对于想深入了解堆内存管理的读者,是一个不错的选择。
可见,VLD 简单易用。只需要做很小的改动(添加库并包含头文件),然后正常运行自己的程序,就可以发现内存问题;如果深入源码,可以学习到堆内存分配与释放的原理、内存泄漏检测的原理及内存操作的常用技巧等。
本人测试系统是 Win10, 测试过 VS2017、2019、2022,都是可以使用 VLD的,以下简单记录一下安装以及使用过程。
安装
VLD 下载地址:https://kinddragon.github.io/vld/,当前最新版本是 vld-2.5.1-setup.exe,下载完成后,双击进行安装即可。在安装目录下会有相应的 include 和 lib 目录。

安装完成后,大部分现有项目以及新建的项目,会自动添加其 include 目录添加到 VS 的附加安装目录,将其 lib 目录添加到 VS 的附加库目录,而无需手动添加。
为什么能自动添加 include 和 lib 目录
安装 VLD 时会把相应的 include 和 lib 目录,添加到 VS 的全局属性配置文件中。本人的配置文件路径是:C:\Users\Administrator\AppData\Local\Microsoft\MSBuild\v4.0,

我们打开 Microsoft.Cpp.Win32.user.props 会看到 VLD 的 include 和 lib 目录已经添加到 AdditionalIncludeDirectories 和 AdditionalLibraryDirectories 属性中。
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets"></ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>C:\Program Files (x86)\Visual Leak Detector\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<Lib>
<AdditionalLibraryDirectories>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
再看项目的属性配置,只要勾选了“从父级或项目默认设置继承”,就可看到继承的值中有 VLD 的 include 或 lib 目录。


为什么现有的项目没有自动添加 include 和 lib 目录
大概率的原因是项目没有包含全局的属性文件 Microsoft.Cpp.Win32.user.props 或 Microsoft.Cpp.x64.user.props 。添加的方法如下:
打开属性管理器

添加全局属性文件


手动编辑工程文件
上面的方法添加的属性文件,是绝对路径的,代码拷贝到其他机器就不一样能使用了,所以可以手动编辑工程文件,例如在 test.vcxproj 中添加如下代码:
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
使用示例
新建一个 Win32 控制台应用程序,在源文件 main.cpp 中包含头文件 vld.h 即可,代码如下:
#include "vld.h"
int main()
{
char* p = new char[10];
return 0;
}
可以从输出窗口中看到,有内存泄漏,并提示了在哪一行

总结
VLD 安装和使用比较简单,也起到了效果。但有一个问题,就是需要在程序退出时才出检测结果。而很多程序(特别是服务器程序),都是一直在运行的,无法运行过程中知道内存的使用情况。而 VS 自带的诊断工具可以满足这方面的需求。
