內存泄漏,通常被定義爲沒有釋放之前分配的內存資源,在C++的程序中這個問題特別難排查。一個很小的內存泄漏可能在初期沒怎麼重視,當時累計多了,會造成大面積的崩潰行爲和性能問題,很典型的原型就是因爲沒有釋放,內存被用完了。更糟糕的是,有可能還會引起其餘的程序訪問無效的內存區域,導致困惑的錯誤。最後都不知道問題出在哪個程序,或者模塊中。
在Linux下和Windows下分別有不同的靜態,動態檢測,分析工具排查此類問題。這裏簡單介紹幾個:
在VisualStudio中可以使用C Run-time (CRT) 庫來偵測內存泄漏。
- 在程序開始的位置,或者對應合適的位置,使用如下代碼
必須保持Inlcude的順序
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
- _CRTDBG_MAP_ALLOC宏定義,讓CRT的堆功能使用對應Debug版本
- 其中crtdbg.h頭文件,讓malloc/free使用其debug版本,malloc_dbg/free 可以跟蹤內存的分配和銷燬,這個行爲只在定義了宏_DEBUG的調試模式有效。
- 在程序結束的位置調用如下函數,
_CrtDumpMemoryLeaks();
如果有多個結束的地方,可以在開始的位置定義如下標記位,這樣它會自動捕捉到出口位置,然後去調用CrtDumpMemoryLeaks()
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
默認情況下,CrtDumpMemoryLeaks函數會將泄漏信息輸出到【輸出】窗口。
如果是一個庫,可以使用如下函數,設置默認位置爲【輸出】窗口
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
最後輸出的內容可能大致如下:
這種方法的具體參考地址:
基於上述的原理,有一個VLD的庫,下載地址:
https://kinddragon.github.io/vld/
下載下來後,使用超級方便,直接在你程序開始的代碼中
#include “vld.h” 即可。(至於這個VLD.h就是庫中的頭文件,引用目錄後使用即可)。
它的輸出信息大約如下:
可以看到內存泄漏的內容,發生的文件信息等。
此外還有很多的C++靜態分析工具,有時候也能提供一點建議和信息,比如CppCheck
官網地址: http://cppcheck.sourceforge.net/
使用方式很簡單,打開GUI界面後,打開目標項目,點擊【掃描】或Analyze即可。幾分鐘後就可以看到各種問題程度等級的信息。從個人角度來看,效果不是特別大,當時作爲一定程度的輔助還是可以試着看看的。
還有一個騰訊的開源靜態掃描,支持C++/GO等語言。
地址: https://github.com/Tencent/TscanCode
獲取下來後,針對各平臺有安裝,安裝後使用。(源代碼編譯貌似少一個config.h文件)
菜單按鈕選擇【掃描文件夾】或文件,幾分鐘後,彈出了結果窗口,如下圖:
相對來說,也是隻能作爲一個參考。