在進行C++開發時,如果在windows平台上,使用MFC,則可以自動檢測內存洩露,如果是win32或者console程序,不使用MFC,則需要自己進行處理。 下面是在總結的一些方法,均來自網上,也經歷了實際檢驗,在此備份。 1. 利用 KDetectMemoryLeak.h來完成類似MFC重定義NEW宏的效果。可以完成洩露點的輸出。 在代碼的最後,采用_CrtDumpMemoryLeaks(); 具體可以參見《VS2008內存洩露檢測》文檔,作者寫的很清楚,在此謝謝。 KDetectMemoryLeak.h 源碼: #pragma once #ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__,__LINE__) #else #define DEBUG_CLIENTBLOCK #endif #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #ifdef _DEBUG #define new DEBUG_CLIENTBLOCK #endif 2. 對於無法定位到具體源代碼的洩露,可以通過分析dump出來的信息來定位。 特別是在DLL庫中,經常會出現這種情況。 比如: {152} normal block at 0x01078320, 12 bytes long. Data: 08 79 65 00 48 82 07 01 00 00 00 00 {151} normal block at 0x010782C0, 36 bytes long. Data: CD CD CD CD CD CD CD CD 00 00 00 00 00 00 0000 {150} normal block at 0x01078248, 56 bytes long. Data: F4 77 65 00 00 00 00 00 68 71 07 01 90 3A 0910 《軟件調試》的702頁介紹了堆塊轉儲的細節,取其中的一個堆塊為例: {137} normal block at 0x01073790, 8 bytes long. Data: <H7> 48 37 07 01 CD CD CD CD 137是堆塊的分配序號,堆塊的類型為普通堆塊,位置為0x01073790,用戶區長度為8字節。 Data後為用戶數據區的前16字節,因為這個數據區只有8字節,所以即所有8字節。<H7>是這8字節的ASCII碼顯示(其它6字節為不可顯示的ASCII碼)。其中的CD CD CDCD 是CRT在分配堆塊時自動填充的固定內容(《軟件調試》P696)。這說明這8個字節的堆塊,應用程序使用過前4個字節,後四個字節沒有使用過。 對於這樣的內存洩漏,有很多種辦法,你首先可以試一下23.13.1節介紹的內存分配序號斷點,也就是重新運行程序,在盡可能早的時候(比如入口),設置序號斷點(將_crtBreakAlloc變量設置為要中斷的序號,比如137),讓CRT分配到指定的內存塊時中斷。中斷下來後,可以根據棧回溯判斷是哪個模塊在分配內存,記錄後,再退出程序,如果這個堆塊仍出現在轉儲列表中,那麼剛才那個模塊便值得懷疑了。 如果你有被懷疑的模塊源代碼,那麼可以使用23.15.3節介紹的方法讓堆塊轉儲信息中包含源程序的文件名和行號,即下面的樣子: C:\dig\dbg\author\code\chap23\MemLeak\MemLeak.cpp(22): {74} normal block at 0x00371000, 20 bytes long. Data: CD CD CD CD CD CD CD CD CD CD CD CD CD CD CDCD 3.可以利用 vld 進行檢測。 4.還可以利用 boundcheck,purify等工具進行檢測。