用VC檢測和隔離內(nèi)存泄漏_第1頁
用VC檢測和隔離內(nèi)存泄漏_第2頁
用VC檢測和隔離內(nèi)存泄漏_第3頁
用VC檢測和隔離內(nèi)存泄漏_第4頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、用VC+檢測和隔離內(nèi)存泄漏具有動態(tài)的分配和釋放內(nèi)存的能力是C/C+程序語言的重要特色之一。Visual C+ debugger 和 CRT庫提供了一系列有效的檢測和鑒定內(nèi)存泄漏的工具。設(shè)置內(nèi)存泄漏檢測檢測內(nèi)存泄漏的基本工具是調(diào)試器和CRT調(diào)試堆函數(shù)。為了使用調(diào)試堆函數(shù),在你的程序中你必須含有下面的說明:#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>#include說明必須按順序說明。如果改變了順序,所用的函數(shù)可能不能正常工作。包含crtdbg.h的_malloc_dbg和 _free_dbg

2、將 malloc和free函數(shù)映射到測試版中,它可以跟蹤內(nèi)存的分配和釋放。這種映射僅僅在一個測試體系中發(fā)生(也就是說,僅僅當(dāng)_DEBUG被定義的時候)。釋放的體系使用通常的malloc和 free功能。#define說明映射CRT堆函數(shù)的低級版本到相應(yīng)的測試版本。這個說明是不需要的,但是沒有它,內(nèi)存泄漏處含有的只是沒有多大用處的信息。一旦你已經(jīng)增加了剛才的說明,你能夠通過在你的程序中包含下面的說明來釋放內(nèi)存信息:_CrtDumpMemoryLeaks();當(dāng)調(diào)試情況下運(yùn)行程序時,在輸出窗口的Debug 標(biāo)簽處_CrtDumpMemoryLeaks表現(xiàn)出內(nèi)存泄漏的信息。內(nèi)存泄漏信息類似下面這樣:

3、Detected memory leaks!Dumping objects ->C:PROGRAM FILESVISUAL STUDIOMyProjectsleaktestleaktest.cpp(20) : 18 normal block at0x00780E80, 64 bytes long.Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD C

4、D CD CD CD Object dump complete. 如果你沒有用#define _CRTDBG_MAP_ALLOC說明,內(nèi)存漏洞堆存處類似下面這樣:Detected memory leaks!Dumping objects ->18 normal block at 0x00780E80, 64 bytes long.Data: <                > CD CD CD CD CD CD CD

5、 CD CD CD CD CD CD CD CD CD Object dump complete.當(dāng)_CRTDBG_MAP_ALLOC被定義時,_CrtDumpMemoryLeaks給了你更多的有用信息。如果_CRTDBG_MAP_ALLOC沒有被定義,那么將向你如下顯示:內(nèi)存分配數(shù)值(花括號內(nèi))模塊的類型(normal、client或者CRT)以十六進(jìn)制格式定位的內(nèi)存以字節(jié)計(jì)模塊的大小第一個十六字節(jié)的內(nèi)容(也可以用十六進(jìn)制)當(dāng)定義了_CRTDBG_MAP_ALLOC的時候,顯示的內(nèi)容也向你展現(xiàn)了出現(xiàn)泄漏內(nèi)存所分配地方的文件。在文件名之后括號內(nèi)的數(shù)字(20,以此為例)是文件內(nèi)的行數(shù)值。如果你雙

6、擊包含行數(shù)值和文件名的輸出行, C:PROGRAM FILESVISUAL STUDIOMyProjectsleaktestleaktest.cpp(20) : 18 normal block at 0x00780E80, 64 bytes long.指針將會跳到源文件中內(nèi)存被分配地方的行(在上面的情況下,leaktest.cpp的行號為20)。選擇輸出行并按F4將有同樣的效果。 使用_CrtSetDbgFlag如果你的程序總是在同一各地方存在,那么調(diào)用_CrtDumpMemoryLeaks時非常容易的。但是,如果你的程序需要在多個位置退出該怎么辦?在每一個可能的出口處如果不調(diào)用_CrtDum

7、pMemoryLeaks,你可在你的程序開始處包含下面的調(diào)用:_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);當(dāng)程序退出時,這個說明自動地調(diào)用_CrtDumpMemoryLeaks。你必須設(shè)置兩個位域,_CRTDBG_ALLOC_MEM_DF和 _CRTDBG_LEAK_CHECK_DF。翻譯內(nèi)存模塊的類型內(nèi)存泄漏信息鑒別泄漏內(nèi)存的每一個模塊作為一個普通的模塊、一個客戶模塊或者一個CRT模塊。實(shí)際上,普通的模塊和客戶模塊是你可能留心的唯一類型。一個普通模塊(normal block)是由你的程序分配的普通內(nèi)存。一個客戶

8、模塊(client block)是一種特殊的內(nèi)存模塊,它由于需要一個析構(gòu)函數(shù)的對象而被Microsoft Foundation Classes (MFC)所使用。MFC new操作子建立一個普通模塊或者一個客戶模塊,來適合被創(chuàng)建的模塊。一個CTR模塊是由CRT庫提供自己使用而分配的內(nèi)存模塊。CRT庫對這些模塊來管理自己的去分配,因此你不可能在內(nèi)存泄漏報告中注意到這些,除非有些地方有嚴(yán)重的錯誤(例如,CRT庫崩潰)。在內(nèi)存泄漏信息中有兩種你從來沒有見過的模塊類型:空閑模塊(free block)是一種被釋放的內(nèi)存模塊Ignore block是你已經(jīng)特殊標(biāo)記過以至于在內(nèi)存泄漏報告中不會出現(xiàn)的模塊。

9、設(shè)置CRT報告樣式像以前的一樣,按默認(rèn)方式,_CrtDumpMemoryLeaks傾卸內(nèi)存泄漏信息到輸出窗口的Debug窗格。你可以運(yùn)用_CrtSetReportMode重新設(shè)置它到堆存處,到另一個位置。如果你使用一個庫,它可能重新設(shè)置輸出到另一個位置。在這種情況下,你能夠利用下面的說明來設(shè)置輸出位置回到輸出窗口:_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );關(guān)于使用_CrtSetReportMode去發(fā)送輸出信息到另一個位置,要看Visual C+文件的_CrtSetReportMode節(jié)。在內(nèi)存分配數(shù)目處設(shè)置一個斷點(diǎn)在內(nèi)存泄漏報告中

10、的文件名和行號可告訴你泄漏的內(nèi)存在那里被分配,但是了解內(nèi)存在那里分配對于鑒定問題不總是充分的。在一個程序運(yùn)行過程中,經(jīng)常是一個分配將會被調(diào)用很多次,但是它可能在某次調(diào)用中泄漏內(nèi)存。為了確定問題,你必須不但知道泄漏的內(nèi)存在那里分配,還要知道泄漏發(fā)生的條件。對你來說,使它成為可能的那條信息是內(nèi)存分配號。當(dāng)那些被顯示的時候,文件名和行號之后,這是在curly brace中出現(xiàn)的數(shù)值。例如,在下面的輸出中,"18"是內(nèi)存分配號。它的意思是泄漏的內(nèi)存是你程序中內(nèi)存分配的第十八個模塊。Detected memory leaks!Dumping objects ->C:PROGRA

11、M FILESVISUAL STUDIOMyProjectsleaktestleaktest.cpp(20) : 18 normal block at 0x00780E80, 64 bytes long.Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete.CRT庫計(jì)算在程序運(yùn)行期間分配的所用

12、內(nèi)存模塊,包括CRT自己分配的內(nèi)存或者諸如MFC的其它模塊。因此帶有分配號n的一個對象是在你的程序中分配的第n個對象,但不可能是由代碼分配的第n個對象。(在大部分情況下,它是不會的。)你可以利用分配號在內(nèi)存分配的地方設(shè)置一個斷點(diǎn)。為了做這些,你可以距離你的程序開始很近處,設(shè)置一個位置斷點(diǎn)。當(dāng)你的程序在那一點(diǎn)暫停時,你能夠從QuickWatch對話框或者Watch窗口設(shè)置這樣一個位置斷點(diǎn)。例如,在Watch窗口中,在Name欄鍵入下面的表達(dá)式: _crtBreakAlloc如果你正在用CRT庫的多線程的dynamic-link library (DLL)版本,你必須含有上下文操作符,像這里說明的

13、:,msvcrtd.dll_crtBreakAlloc現(xiàn)在,按RETURN。調(diào)試器評估調(diào)用并且把結(jié)果放置在Value欄。如果你在內(nèi)存分配過程中還沒有設(shè)置任何斷點(diǎn),那么這個值是1。使用你想中斷處內(nèi)存分配的分配數(shù)值來代替Value表中的值-例如,18 去中斷早期在輸出過程中展現(xiàn)的分配。當(dāng)你在你感興趣的內(nèi)存分配處設(shè)置斷點(diǎn)之后,你能夠繼續(xù)調(diào)試。在與從前相同的條件下,運(yùn)行程序時一定要小心,因而分配的順序不會改變。當(dāng)你的程序在一個特殊的內(nèi)存分配點(diǎn)中斷的時候,你能夠查看Call Stack窗口和其他的測試信息來確定在此條件下內(nèi)存的分配。如果需要的話,你可以繼續(xù)從那一點(diǎn)執(zhí)行程序,以至于了解對象到底發(fā)生了什么事

14、,同時還可能確定為了沒有正確地被去分配。(對對象設(shè)置一個數(shù)據(jù)斷點(diǎn)是很有幫助的。)雖然在調(diào)試器中設(shè)置內(nèi)存分配斷點(diǎn)通常更加容易,但是如果你喜歡的話,你可以在你的代碼中設(shè)置它們。為了在你的代碼中設(shè)置一個內(nèi)存分配斷點(diǎn),可以增加這樣一行(對于第十八個內(nèi)存分配): _crtBreakAlloc = 18;最后一個選擇,你可以使用有相同效果的_CrtSetBreakAlloc函數(shù)。_CrtSetBreakAlloc(18);比較內(nèi)存狀態(tài)定位內(nèi)存泄漏的另一個方法就是在關(guān)鍵點(diǎn)對應(yīng)用程序的內(nèi)存狀態(tài)做快照。CRT庫提供了一個結(jié)構(gòu)類型,_CrtMemState。你可以使用它來存儲內(nèi)存狀態(tài)的一個快照。_CrtMemSt

15、ate s1, s2, s3;為了在特定點(diǎn)對內(nèi)存狀態(tài)進(jìn)行快照,可以傳遞一個_CrtMemState結(jié)構(gòu)到he _CrtMemCheckpoint函數(shù)。此函數(shù)用當(dāng)時內(nèi)存狀態(tài)的一個快照來填充此結(jié)構(gòu): _CrtMemCheckpoint( &s1);你可以通過傳遞此結(jié)構(gòu)到_CrtMemDumpStatistics函數(shù)來傾卸_CrtMemState結(jié)構(gòu)的任意點(diǎn)的內(nèi)容:_CrtMemDumpStatistics( &s3 );( &s1 );此函數(shù)打印出類似于下面這樣的一堆內(nèi)存分配信息:0 bytes in 0 Free Blocks.0 bytes in 0 Normal Bl

16、ocks.3071 bytes in 16 CRT Blocks.0 bytes in 0 Ignore Blocks.0 bytes in 0 Client Blocks.Largest number used: 3071 bytes.Total allocations: 3764 bytes.為了確定一個內(nèi)存泄漏是否在一節(jié)代碼中出現(xiàn),你可以在此節(jié)前和此節(jié)后對內(nèi)存狀態(tài)作快照,然后用_CrtMemDifference比較兩種狀態(tài): _CrtMemCheckpoint( &s1 );/ memory allocations take place here_CrtMemCheckpoint( &s2 );if ( _CrtMemDifference( &s3, &s1, &s2) )   &

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論