使用 VLD 內(nèi)存泄漏檢測工具輔助開發(fā)時整理的學(xué)習(xí)筆記。
目錄說明1. 使用方式2. 測試代碼3. 使用 32 bit 編譯器時的輸出4. 使用 64 bit 編譯器時的輸出5. 輸出報告對比結(jié)果1. 使用方式在 QT 中使用 VLD 的方法可以查看另外幾篇博客:
【Visual Leak Detector】在 QT 中使用 VLD(方式一)
(相關(guān)資料圖)
【Visual Leak Detector】在 QT 中使用 VLD(方式二)
【Visual Leak Detector】在 QT 中使用 VLD(方式三)
本次測試使用的環(huán)境為:QT 5.9.2,Debug模式,VLD 版本為 2.5.1,VLD 配置文件不做任何更改使用默認配置,測試工程所在路徑為:E:\Cworkspace\Qt 5.9\QtDemo\testVLD
。
寫一個有一處內(nèi)存泄漏的程序,如下:
#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編譯器,程序運行時,在標準輸出窗會輸出以下結(jié)果:
ptr = 0070a3d0, *ptr = 55345678
程序運行結(jié)束后,檢測到了內(nèi)存泄漏,VLD 會輸出以下報告(本例中出現(xiàn)一處內(nèi)存泄漏),第 1~3 行顯示 VLD 運行狀態(tài),第 4~21 行顯示泄漏內(nèi)存的詳細信息,第 22~24 行總結(jié)此次泄漏情況,第 25 行顯示 VLD 退出狀態(tài)。
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編譯器,程序運行時,在標準輸出窗會輸出以下結(jié)果:
ptr = 25a42da0, *ptr = 55345678
程序運行結(jié)束后,檢測到了內(nèi)存泄漏,VLD 會輸出以下報告(本例中出現(xiàn)一處內(nèi)存泄漏),第 1~3 行顯示 VLD 運行狀態(tài),第 4~21 行顯示泄漏內(nèi)存的詳細信息,第 22~24 行總結(jié)此次泄漏情況,第 25 行顯示 VLD 退出狀態(tài)。
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. 輸出報告對比結(jié)果使用不同位數(shù)的編譯器時,輸出報告的差異主要體現(xiàn)在以下幾點:
地址的表示位數(shù)不同,32 bit 編譯器使用 8 位十六進制數(shù)表示,64 bit 編譯器使用 16 位十六進制數(shù)表示。體現(xiàn)在輸出的第 4 行,分別為0x0070A3D0
和 0x0000000025A42DA0
。程序啟動時所調(diào)用的 Windows
操作系統(tǒng)函數(shù)不完全相同,32 bit 編譯器調(diào)用了兩次 RtlGetAppContainerNamedObjectPath()
函數(shù)和一次 BaseThreadInitThunk()
函數(shù),64 bit 編譯器只調(diào)用了一次 RtlUserThreadStart()
函數(shù)和一次 BaseThreadInitThunk()
函數(shù),且它們調(diào)用 BaseThreadInitThunk()
函數(shù)時泄漏指令的內(nèi)存偏移量不同,32 bit 編譯器是 0x19 bytes
,而 64 bit 編譯器是 0x14 bytes
。內(nèi)存管理頭的寬度不同,32 bit 編譯器時是 36 bytes
,64 bit 編譯器時是 52 bytes
。體現(xiàn)在輸出的倒數(shù)第二行,分別為 Total allocations: 40 bytes
和 Total allocations: 56 bytes
,將代碼請求的內(nèi)存大小 4 bytes
加上各自管理頭的內(nèi)存大小,可以得到與輸出一致的結(jié)果: \(4 + 36 = 40bytes\) 及 \(4 + 52 = 56bytes\)。 Copyright © 2015-2022 華中時尚網(wǎng)版權(quán)所有 備案號:京ICP備12018864號-26 聯(lián)系郵箱:2 913 236 @qq.com