说明
使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍如何在 Release 模式下使用 VLD。同系列文章目录可见 《内存泄漏检测工具》目录
1. 思路概述
要在 RELEASE
模式下使用 VLD,必须在包含头文件 vld.h
前预先定义 VLD_FORCE_ENABLE
宏(参考 VLD Issues 46):
#define VLD_FORCE_ENABLE
#include "vld.h"
与 DEBUG
模式一样,可以在代码中使用 VLDGlobalEnable
、VLDReportLeaks
、VLDGlobalDisable
等 VLD 库提供的 API,也可以通过提前更改 vld.ini
配置文件,实现对 VLD 功能的定制。API 使用方法可查看 vld.h
头文件或本人同系列文章。
2. 在 QT 中实践
本次测试使用的环境为:QT 5.9.2,MSVC 2015 32bit,Release 模式,VLD 版本为 2.5.1,VLD 配置文件不做任何更改使用默认配置,测试工程所在路径为:E:\Cworkspace\Qt 5.9\QtDemo\testVLD
。测试代码如下:
#include <QCoreApplication>
#define VLD_FORCE_ENABLE
#include "vld.h"
void testFun(int i)
{
int *ptr = new int(i);
printf("ptr = %08x, *ptr = %08x.\n", ptr, *ptr);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
testFun(1);
return a.exec();
}
运行结束后,标准输出窗中输出以下结果:
ptr = 00e48270, *ptr = 00000001.
程序运行结束后,输出以下报告:
Visual Leak Detector read settings from: D:\Program Files (x86)\Visual Leak Detector\vld.ini
Visual Leak Detector Version 2.5.1 installed.
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x00E48270: 4 bytes ----------
Leak Hash: 0xBE4F898C, Count: 1, Total 4 bytes
Call Stack (TID 37180):
ucrtbase.dll!malloc()
testVLD.exe!0x00A510FA()
testVLD.exe!0x00A51059()
testVLD.exe!0x00A512C6()
KERNEL32.DLL!BaseThreadInitThunk() + 0x19 bytes
ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0x11E bytes
ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0xEE bytes
Data:
01 00 00 00 ........ ........
Visual Leak Detector detected 1 memory leak (4 bytes).
Largest number used: 4 bytes.
Total allocations: 4 bytes.
Visual Leak Detector is now exiting.
为了与 DEBUG
模式下的输出做比较,切换为 DEBUG
模式后的输出报告如下:
Visual Leak Detector read settings from: D:\Program Files (x86)\Visual Leak Detector\vld.ini
Visual Leak Detector Version 2.5.1 installed.
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x01123E48: 4 bytes ----------
Leak Hash: 0x57574D54, Count: 1, Total 4 bytes
Call Stack (TID 28696):
ucrtbased.dll!malloc()
f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): testVLD.exe!operator new() + 0x9 bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (8): testVLD.exe!testFun() + 0x7 bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (16): testVLD.exe!main() + 0x7 bytes
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (74): testVLD.exe!invoke_main() + 0x1B bytes
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (264): testVLD.exe!__scrt_common_main_seh() + 0x5 bytes
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): testVLD.exe!__scrt_common_main()
f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): testVLD.exe!mainCRTStartup()
KERNEL32.DLL!BaseThreadInitThunk() + 0x19 bytes
ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0x11E bytes
ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0xEE bytes
Data:
01 00 00 00 ........ ........
Visual Leak Detector detected 1 memory leak (40 bytes).
Largest number used: 40 bytes.
Total allocations: 40 bytes.
Visual Leak Detector is now exiting.
比较可知,RELEASE
模式下的报告,调用堆栈信息不够详细,且泄漏总内存中没有用于内存管理头的额外 36 bytes
。
- Detector Release 模式 Visual Leakdetector release模式visual detector visual leak vld detector方式visual leak skipheapfreeleaks detector visual leak 源码detector visual leak detector visual leak 2015 skipcrtstartupleaks detector visual leak forceincludemodulesmd detector visual leak stackwalkmethod detector visual leak detector版本visual leak