內(nèi)存泄漏是指程序中己動(dòng)態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放,造成系統(tǒng)內(nèi)存的浪費(fèi),導(dǎo)致程序運(yùn)行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果。,下面讓我們來介紹如何使用這個(gè)小巧的工具。將h文件拷貝到C++的默認(rèn)目錄下,將lib文件拷貝到C++的默認(rèn)lib目錄下,便安裝完成了。接下來需要將其加入到自己的代碼中。方法很簡(jiǎn)單,只要在包含入口函數(shù)的cpp文件中包含vldh就可以。接下來讓我們來演示如何使用Leak檢測(cè)內(nèi)存泄漏。
會(huì)出現(xiàn)內(nèi)存泄漏,什么原因
內(nèi)存泄漏是指程序中已經(jīng)動(dòng)態(tài)分配的堆內(nèi)存沒有被釋放或者由于某種原因無法釋放,造成系統(tǒng)內(nèi)存的浪費(fèi),減緩程序的運(yùn)行速度,甚至造成系統(tǒng)崩潰等嚴(yán)重后果。
VisualLeakDetector內(nèi)存泄露檢測(cè),該怎么處理
下面介紹一下這個(gè)小工具的使用方法。首先,從網(wǎng)站下載zip包。解壓后可以得到vld.h,。h,vld.lib,。lib,。lib,。dll和其他文件。復(fù)制。h文件復(fù)制到C++的默認(rèn)目錄中。lib文件到C++的默認(rèn)lib目錄,安裝就完成了。由于版本問題,如果您使用2000或更早的版本,您需要復(fù)制。dll到程序的運(yùn)行目錄,或者其他可以被引用的目錄。接下來,您需要將其添加到您自己的代碼中。方法很簡(jiǎn)單,只要把vld.h包含在。包含入口函數(shù)的cpp文件。如果這個(gè)cpp文件包含。將包含vld.h的語句放在包含。h,否則放前面。下面是一個(gè)示例程序#voidmain(){…}接下來,讓我們演示如何使用Leak來檢測(cè)內(nèi)存泄漏。下面是一個(gè)簡(jiǎn)單的程序,它用new分配一個(gè)int大小的堆內(nèi)存,并且不釋放它。應(yīng)用程序的內(nèi)存地址被輸出到屏幕上。# # # VoidF(){ int * p = new int()(" p = % 08x,",p)}voidmain(){f()}編譯運(yùn)行后,在標(biāo)準(zhǔn)輸出窗口中g(shù)et p =在C++窗口中g(shù)et Leakleaks!- Block5,AT4Bytes - Rtm CRT src 。c (586,f RTM CRT src 。c (403,(Fileandlinenot)數(shù)據(jù)——這是泄露內(nèi)存的內(nèi)容,7,5,3,1,xV4,............泄漏1。在程序的第7行,在f()函數(shù)中,在這個(gè)地址分配了4個(gè)字節(jié)的堆內(nèi)存空間,并賦值給,這樣在報(bào)表中,我們就可以看到這4個(gè)字節(jié)的相同內(nèi)容??梢钥吹?,對(duì)于每一個(gè)內(nèi)存泄漏,這個(gè)報(bào)告都列出了它的泄漏點(diǎn)、長(zhǎng)度、分配內(nèi)存時(shí)的調(diào)用棧以及泄漏內(nèi)存的內(nèi)容(分別以十六進(jìn)制和文本格式列出)。雙擊堆棧報(bào)告的一行將自動(dòng)跳轉(zhuǎn)到它在代碼編輯器中引用的文件的相應(yīng)行。這些信息對(duì)于我們發(fā)現(xiàn)內(nèi)存泄漏會(huì)有很大的幫助。這是一個(gè)非常方便易用的工具。每次安裝后使用它,只需要包含它的頭文件并編譯即可。而且,該工具只有在調(diào)試版本構(gòu)建時(shí)才會(huì)連接到你的程序,如果使用了構(gòu)建版本,該工具對(duì)你的程序性能不會(huì)有任何影響。所以你可以在你的源代碼中包含它的頭文件。Leak如何工作讓我們來看看這個(gè)工具是如何工作的。在此之前,我們先來看看C++內(nèi)置的內(nèi)存泄漏檢測(cè)工具是如何工作的。C++內(nèi)置工具CRTDebugHeap工作起來非常簡(jiǎn)單。當(dāng)使用調(diào)試版本分配內(nèi)存時(shí),所分配內(nèi)存的文件名和行號(hào)將被記錄在內(nèi)存塊的頭中。程序退出時(shí),CRT會(huì)在main()函數(shù)返回后做一些清理工作。此時(shí),檢查調(diào)試堆內(nèi)存。如果還有內(nèi)存沒有被釋放,那么一定是內(nèi)存泄漏。從這些未釋放的內(nèi)存塊的頭中,可以獲得文件名和行號(hào)。這個(gè)靜態(tài)方法可以檢測(cè)內(nèi)存泄漏以及泄漏點(diǎn)的文件名和行號(hào),但是它不知道泄漏是如何發(fā)生的,也不知道內(nèi)存分配語句是如何執(zhí)行的。要理解這一點(diǎn),需要?jiǎng)討B(tài)跟蹤程序的內(nèi)存分配過程。泄漏就是這么做的。它記錄每個(gè)內(nèi)存分配的上下文,當(dāng)程序退出時(shí),它在記錄的上下文信息中搜索檢測(cè)到的內(nèi)存泄漏,并將其轉(zhuǎn)換為報(bào)告輸出。Leak的初始化記錄了每一次內(nèi)存分配,它是如何監(jiān)控內(nèi)存分配的?分配掛鉤用于監(jiān)控調(diào)試堆內(nèi)存的分配。它是一個(gè)用戶定義的回調(diào)函數(shù),在每次從調(diào)試堆分配內(nèi)存之前調(diào)用。在初始化期間,Leak使用register hook函數(shù),這樣它就可以從那時(shí)起監(jiān)控所有堆內(nèi)存分配。如何保證在泄露初始化之前沒有堆內(nèi)存分配?程序啟動(dòng)時(shí),全局變量被初始化。如果使用Leak作為全局變量,可以用程序啟動(dòng)。但是C/C++并沒有規(guī)定全局變量之間的初始化順序。如果在其他全局變量的構(gòu)造函數(shù)中有堆內(nèi)存分配,可能檢測(cè)不到。Leak使用C/C++提供的#在一定程度上降低了其他全局變量在它之前被初始化的概率。根據(jù)#的定義,初始化