vs記憶體洩漏檢處理

2021-10-09 04:24:55 字數 2674 閱讀 1000

#define _crtdbg_map_alloc #include #include

注:#include 語句必須採用上文所示順序。如果更改了順序,所使用的函式可能無法正確工作。 到這裡,對malloc等的呼叫,都會被記錄下來,但執行一遍程式,會發現,並沒有列印任何洩漏資訊。這是因為目前為止,只記錄了記憶體分配,並沒有輸出資訊。 輸出記錄的未釋放記憶體,是通過呼叫_crtdumpmemoryleaks();實現。_crtdumpmemoryleaks的作用就是收集所有未釋放的記憶體資訊,並列印出來。所以,通常_crtdumpmemoryleaks要放到程式結束的位置。但乙個程式往往有多個結束的位置,並且,_crtdumpmemoryleaks列印的是執行_crtdumpmemoryleaks的時候,未釋放的記憶體。有些記憶體,往往在_crtdumpmemoryleaks之後釋放,_crtdumpmemoryleaks仍然會報告出洩漏。

解決方法是:在程式開始處呼叫: _crtsetdbgflag(_crtdbg_alloc_mem_df | _crtdbg_leak_check_df); 該語句在程式退出時自動呼叫 _crtdumpmemoryleaks,我們不需要再呼叫_crtdumpmemoryleaks列印報告了。

高階篇: 在_crtdumpmemoryleaks中加斷點發現,當呼叫了_crtsetdbgflag(_crtdbg_alloc_mem_df | _crtdbg_leak_check_df)之後,vc程式會在__dllmaincrtstartup函式中處理(dwreason == dll_process_detach)分支時,呼叫_crt_init,而_crt_init內部,呼叫了_crtdumpmemoryleaks。

1.2 對於c++分配的記憶體 #ifdef _debug #define new new(_normal_block,file,line) #endif

通過巨集定義,把對new的呼叫,對映到帶檔名和行號引數的operator new函式上,並最終呼叫到_heap_alloc_dbg_impl,並把分配記憶體的檔名、行號傳遞給_heap_alloc_dbg_impl。

注:_normal_block也是在#include 中定義。並且c++分配的記憶體,也需要呼叫_crtdumpmemoryleaks列印報告(可通過程式入口出呼叫_crtsetdbgflag來避免對_crtdumpmemoryleaks的直接呼叫)。

二、對於mfc程式 mfc工程,最終也是按win32工程方式的記憶體洩漏執行,不過mfc工程建立嚮導生成的mfc工程,自動支援c++分配的記憶體洩漏檢測,我們不需要任何處理。

2.1 對於c++分配的記憶體 mfc是通過下面的語句支援的: #ifdef _debug #define new debug_new #endif

我們簡單分析一下: 在mfc中,debug_new也是個巨集,定義為: #define debug_new new(this_file,line) 所以,在mfc debug下,呼叫new操作符,會使用 void* __cdecl operator new(size_t nsize, lpcstr lpszfilename, int nline) 來分配記憶體,而operator new最終會呼叫到_heap_alloc_dbg_impl,並把分配記憶體的檔名、行號傳遞給_heap_alloc_dbg_impl。 當我們呼叫delete刪除記憶體時,operator delete函式會最終執行_free_dbg_nolock,而_free_dbg_nolock內部,會把待刪除的指標的記錄,從_pfirstblock鍊錶中刪除。 當程式結束時,_pfirstblock會檢測鍊錶中未刪除的記憶體,給出記憶體洩漏報告。

需要注意的是,並不是每個cpp檔案中,都定義了debug_new,尤其後新增的檔案。

2.2 對於c分配的記憶體。 預設不顯示檔名和行號。我們最終的目的,是讓對malloc等函式的呼叫,呼叫到_malloc_dbg等函式上(因為只有_malloc_dbg才接收帶檔名和行號的引數)。而中,已把malloc對映到_malloc_dbg上了。但mfc程式,也做了對malloc的對映。所以,我們只要在mfc程式的stdafx.**件中、在 #include // mfc core and standard components 之前,包含下面的**即可: #define _crtdbg_map_alloc #include #include

注意,這些對映有_crtdbg_map_alloc這個條件巨集,所以要先定義它。

#ifdef _debug

#define debug_clientblock new( _client_block, __file__, __line__)

#else

#define debug_clientblock

#endif

#define _crtdbg_map_alloc

#include

#include

#ifdef _debug

#define new debug_clientblock

#endif

//或者在程序入口處包含_crtsetdbgflag(_crtdbg_alloc_mem_df | _crtdbg_leak_check_df);

//程序出口處包含 _crtdumpmemoryleaks();

//即可檢測到記憶體洩露

//以如下測試函式為例:

intmain()

記憶體洩漏檢測

一 記憶體洩漏 記憶體洩漏是程式設計中常常見到的乙個問題.記憶體洩漏往往會一種奇怪的方式來表現出來,基本上每個程式都表現出不同的方式.但是一般 最後的結果只有兩個,乙個是程式當掉.乙個是系統記憶體不足.還有一種就是比較介於中間的結果程式不會當,但是系統的反映時間明顯降低,需要定時的 reboot才會...

記憶體洩漏檢測

一 記憶體洩漏 記憶體洩漏是程式設計中常常見到的乙個問題.記憶體洩漏往往會一種奇怪的方式來表現出來,基本上每個程式都表現出不同的方式.但是一般最後的結果只有兩個,乙個是程式當掉.乙個是系統記憶體不足.還有一種就是比較介於中間的結果程式不會當,但是系統的反映時間明顯降低,需要定時的reboot才會正常...

記憶體洩漏檢測

記憶體洩漏檢測 自己寫的 作者 很土 關鍵字 記憶體洩漏 記憶體 debug heap 堆 原作者姓名 很土 介紹簡單說明了一下沒有工具的情況如何運用vc庫中的工具來檢查 的記憶體洩漏問題 讀者評分 8 評分次數 2 正文記憶體洩漏檢測 一 記憶體洩漏 記憶體洩漏是程式設計中常常見到的乙個問題.記憶...