C++的內存泄漏檢測


C++大量的手動分配、回收內存是存在風險的,也許一個函數中一小塊內存泄漏被重復放大之后,最后掏空內存。

這里介紹一種在debug模式下測試內存泄漏的方法。

 

首先在文件的開頭以確定的順序寫下這段代碼:

1 #define _CRTDBG_MAP_ALLOC
2 #include <crtdbg.h>
3 #include <stdlib.h>

第1行定義了宏,實現一些內存分配函數向debug模式的映射。

打開<crtdbg.h>我們可以找到這么一段代碼:

可以看到,定義了_DEBUG情況下,定義_CRTDBG_MAP_ALLOC會將函數映射為_dbg的版本。

 

第二個步驟,對new做一個重定義

1 #define NEW_WITH_MEMORY_LEAK_CHECKING new(_NORMAL_BLOCK,__FILE__,__LINE__)
2 #define new    NEW_WITH_MEMORY_LEAK_CHECKING

這里new采用的是VC++對operator new的一個重載,可以在<vcruntime_new_debug.h>中找到,這里不多講了。

 

完成以上兩步之后,程序中new和delete回收的過程便被VC++監視了,在程序退出的地方采用

1 _CrtDumpMemoryLeaks();

便可以在“輸出”窗口查看報告了。

舉個栗子

 1 #define _CRTDBG_MAP_ALLOC
 2 #include <stdlib.h>
 3 #include <crtdbg.h>
 4 #define NEW_WITH_MEMORY_LEAK_CHECKING new(_NORMAL_BLOCK,__FILE__,__LINE__)
 5 #define new    NEW_WITH_MEMORY_LEAK_CHECKING
 6 
 7 int main()
 8 {
 9     auto p = new int[10];
10     _CrtDumpMemoryLeaks();
11     return 0;
12 }

這里還有一點,VC++的編譯器cl.exe在delete之后會將內存置為0xcdcd防止再次利用,這里顯然是程序結束時對p進行了回收。

 

此外,還要介紹一個new的玩法。

(尤其標准庫中很突出)C++程序使用了placement new,這里我不是要介紹這個用法,想了解的自行。

placement new在new后邊跟了括號,這會和上面提到的VC++重載的new沖突,那么怎么避免,在其他地方宏定義了新的new而和placement new沖突的情況?

相信大家一定見過像下面的代碼

1 #pragma push_macro("new")
2 #undef new
3 //using the raw new
4 #pragma pop_macro("new")

#pragma push/pop_macro將宏定義名壓/彈棧,這里現將宏new壓棧,保留原來的定義,之后取消定義,使用原生的new,使用完畢后彈棧恢復宏定義。

 

以上是我介紹的對new出來的內存進行泄漏檢測的簡單方法,以及延伸出的一點常用技巧。

感謝閱讀


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM