使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。
目录说明1. 使用方式2. 测试代码3. 使用 32 bit 编译器时的输出4. 使用 64 bit 编译器时的输出5. 输出报告对比结果1. 使用方式在 QT 中使用 VLD 的方法可以查看另外几篇博客:
【Visual Leak Detector】在 QT 中使用 VLD(方式一)
(相关资料图)
【Visual Leak Detector】在 QT 中使用 VLD(方式二)
【Visual Leak Detector】在 QT 中使用 VLD(方式三)
本次测试使用的环境为:QT 5.9.2,Debug模式,VLD 版本为 2.5.1,VLD 配置文件不做任何更改使用默认配置,测试工程所在路径为:E:\Cworkspace\Qt 5.9\QtDemo\testVLD
。
写一个有一处内存泄漏的程序,如下:
#include #include "vld.h"void testFun(){ int *ptr = new int(0x55345678); printf("ptr = %08x, *ptr = %08x", ptr, *ptr);}int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); testFun(); return a.exec();}
3. 使用 32 bit 编译器时的输出使用 MSVC 2015 32bit编译器,程序运行时,在标准输出窗会输出以下结果:
ptr = 0070a3d0, *ptr = 55345678
程序运行结束后,检测到了内存泄漏,VLD 会输出以下报告(本例中出现一处内存泄漏),第 1~3 行显示 VLD 运行状态,第 4~21 行显示泄漏内存的详细信息,第 22~24 行总结此次泄漏情况,第 25 行显示 VLD 退出状态。
Visual Leak Detector read settings from: D:\Program Files (x86)\Visual Leak Detector\vld.iniVisual Leak Detector Version 2.5.1 installed.WARNING: Visual Leak Detector detected memory leaks!---------- Block 1 at 0x0070A3D0: 4 bytes ---------- Leak Hash: 0xA7ED883D, Count: 1, Total 4 bytes Call Stack (TID 20672): 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 (6): testVLD.exe!testFun() + 0x7 bytes e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (16): testVLD.exe!main() 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: 78 56 34 55 xV4U.... ........Visual Leak Detector detected 1 memory leak (40 bytes).Largest number used: 40 bytes.Total allocations: 40 bytes.Visual Leak Detector is now exiting.
4. 使用 64 bit 编译器时的输出使用 MSVC 2015 64bit编译器,程序运行时,在标准输出窗会输出以下结果:
ptr = 25a42da0, *ptr = 55345678
程序运行结束后,检测到了内存泄漏,VLD 会输出以下报告(本例中出现一处内存泄漏),第 1~3 行显示 VLD 运行状态,第 4~21 行显示泄漏内存的详细信息,第 22~24 行总结此次泄漏情况,第 25 行显示 VLD 退出状态。
Visual Leak Detector read settings from: D:\Program Files (x86)\Visual Leak Detector\vld.iniVisual Leak Detector Version 2.5.1 installed.WARNING: Visual Leak Detector detected memory leaks!---------- Block 1 at 0x0000000025A42DA0: 4 bytes ---------- Leak Hash: 0x92ED96C9, Count: 1, Total 4 bytes Call Stack (TID 16444): ucrtbased.dll!malloc() f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): testVLD.exe!operator new() + 0xA bytes e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (6): testVLD.exe!testFun() + 0xA bytes e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (16): testVLD.exe!main() f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (75): testVLD.exe!invoke_main() 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() + 0x14 bytes ntdll.dll!RtlUserThreadStart() + 0x21 bytes Data: 78 56 34 55 xV4U.... ........Visual Leak Detector detected 1 memory leak (56 bytes).Largest number used: 56 bytes.Total allocations: 56 bytes.Visual Leak Detector is now exiting.
5. 输出报告对比结果使用不同位数的编译器时,输出报告的差异主要体现在以下几点:
地址的表示位数不同,32 bit 编译器使用 8 位十六进制数表示,64 bit 编译器使用 16 位十六进制数表示。体现在输出的第 4 行,分别为0x0070A3D0
和 0x0000000025A42DA0
。程序启动时所调用的 Windows
操作系统函数不完全相同,32 bit 编译器调用了两次 RtlGetAppContainerNamedObjectPath()
函数和一次 BaseThreadInitThunk()
函数,64 bit 编译器只调用了一次 RtlUserThreadStart()
函数和一次 BaseThreadInitThunk()
函数,且它们调用 BaseThreadInitThunk()
函数时泄漏指令的内存偏移量不同,32 bit 编译器是 0x19 bytes
,而 64 bit 编译器是 0x14 bytes
。内存管理头的宽度不同,32 bit 编译器时是 36 bytes
,64 bit 编译器时是 52 bytes
。体现在输出的倒数第二行,分别为 Total allocations: 40 bytes
和 Total allocations: 56 bytes
,将代码请求的内存大小 4 bytes
加上各自管理头的内存大小,可以得到与输出一致的结果: \(4 + 36 = 40bytes\) 及 \(4 + 52 = 56bytes\)。 Copyright © 2015-2022 大河时尚网版权所有 备案号:京ICP备2022022245号-75 联系邮箱:435 226 40@qq.com