- 下载 vld
https://github.com/KindDragon/vld
- 安装 vld 后记录安装目录
C:\Program Files (x86)\Visual Leak Detector
- 拷贝 bin目录下文件到当前源码目录中
拷贝至
将 头文件和lib库引入工程文件
放入源码目录 上一层 和 .sln 一个文件夹
Include/vld 文件夹
Lib 文件夹
头文件,注意 vld 需要在 #include <afxwin.h> 头文件之前使用
#define VLD_FORCE_ENABLE
#include "../Include/vld/vld.h"
#pragma comment(lib, "../lib/vld.lib")
在main函数中使用
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
if(!AfxWinInit(::GetModuleHandle(NULL),NULL,::GetCommandLine(),0))
{
return 1;
}
// 使用 vld 宏开启
VLDGlobalEnable();
VLDReportLeaks();
// 让 mfc 出现命令行窗口方便调试
AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
.... 编写代码
// 关闭 vld 使用
VLDGlobalDisable();
}
关闭程序前,程序会卡死,然后所有的 vld 记录会在 输出(调试)中
vld 使用更多方式:
VLD支持多样化的检测设置接口,具体如下:
1. 单一线程的内存泄漏排查
1) VLDDisable 禁用当前线程的内存泄漏检测
2) VLDEnable 启用当前线程的内存泄漏检测
3) VLDRestore 还原当前线程的内存泄漏检测设置到上一个状态
利用这个方法,可以做到只检测特定线程的内存泄漏,也可以排除此特定线程的内存泄漏检测。
2. 整个程序的内存泄漏排查
1) VLDGlobalDisable
2) VLDGlobalEnable
利用这个方法,可以做到只检测特定阶段的内存泄漏,比如程序启动过程中的内存泄漏,不进行检测,只能当程序初始化完成后,再启动检测。
3. 针对特定模块来使用内存泄漏排查
1) VLDEnableModule
2) VLDDisableModule
4. 获取相关的泄漏信息
#define VLDReportLeaks() (0) 打印整个程序当前执行此函数前的内存泄漏
#define VLDReportThreadLeaks() (0) 打印特定线程在执行此函数前的内存泄漏
#define VLDGetLeaksCount() (0) 获取整个程序当前的内存泄漏数量
#define VLDGetThreadLeaksCount() (0) 获取指定线程当前的内存泄漏数量
#define VLDMarkAllLeaksAsReported() 标记当前的泄漏为已经报告过,后续不再报告
#define VLDMarkThreadLeaksAsReported(a) 标记指定线程当前的泄漏为已经报告过,后续不再报告
5. 其他高级功能
#define VLDRefreshModules() 刷新加载的模块列表,以便针对动态加载的模块进行内存泄漏检查
#define VLDGetOptions() (0) 获取检测的设置 (不太清楚)
#define VLDGetReportFilename(a) 获取泄漏报告生成的文件夹名
#define VLDSetOptions(a, b, c) 设置检测选项
#define VLDSetReportHook(a, b) 自定义的内存泄漏报告回调函数(不清楚)
#define VLDSetModulesList(a) 设置要包含或者排除泄漏检测的模块列表
#define VLDGetModulesList(a, b) (FALSE) 获取检测中的模块列表
#define VLDSetReportOptions(a, b)
#define VLDResolveCallstacks() (0)
更多信息直接查看官方文档及代码注释。
三. 如何避免内存泄漏
1. 避免堆内存申请
2. 使用智能指针来管理堆内存的申请与释放
这里备份留存,原文链接:https://blog.csdn.net/tragicguy/article/details/54311649
其它:
vld 介绍说支持 2008 — 2015 的vs,但是实际测试中,我使用 vs2017 也是正常使用的