我們的代碼裡會有很多的記憶體流失,如何快速的定位和修複這些記憶體的泄漏是一項非常重要的技能,在這裡分享一下如何從開發的代碼裡找到這種問題。
常見的C++程式分為兩大類:MFC和Win32。先看第一種MFC程式如何找記憶體流失的問題。
MFC程式比較容易一些,因為它已經提供了這個功能,我們建立一個MFC的工程,我們在看到每一個CPP檔案裡面都有這樣一句:
1: #ifdef _DEBUG
2: #define new DEBUG_NEW
3: #endif
DEBUG_NEW 這個宏定義在afx.h檔案中,就是它協助我們定位記憶體流失。
在含有以上代碼的cpp檔案中分配記憶體後假如沒有進行釋放,那麼停止程式的時候,VisualStudio的Output視窗就會顯示一些提示的資訊了,試一下:在裡面加一句
int* p = new int;
然後調試工程,運行結束後你會看到在Output視窗裡輸出了
1: Detected memory leaks!
2: Dumping objects ->
3: e:\學習\de\de\de.cpp(20) : {290} normal block at 0x004CD7F8, 4 bytes long.
4: Data: < > CD CD CD CD
5: Object dump complete.
6: The program '[11088] de.exe: Native' has exited with code 0 (0x0).
告訴我們在20行有記憶體流失,雙擊這雙就會跳到相應的程式碼,是不是很方便啊!
下來再看一下Win32工程如何找到記憶體流失:
我試了下用VisualStudio建立的Win32 Console Application和Win32 Project項目,結果都不能檢測出記憶體泄露。
所以我們需要找到如何讓VS幫我發現問題的方法。查詢了MSDN後,發現有個叫Debug Routines的東東。首先,我們需要知道C運行庫的Debug版本提供了許多檢測功能,使得我們更容易的Debug程式。
我們將會使用到裡面很重要的幾個函數。其中最重要的是 _CrtDumpMemoryLeaks使用這個函數,需要包含標頭檔crtdbg.h
該函數只在Debug版本才有用,當在調試器下運行程式時,_CrtDumpMemoryLeaks 將在“Output(輸出)”視窗中顯示記憶體流失資訊.寫段代碼實驗一下吧,如下:
這個就會在Output視窗輸出如下資訊:
雖然輸出了有記憶體流失,但是無法看出是那裡泄漏了,然後下來看看我們的第二個版本的代碼:
它會在Output輸出:
已經很清楚我告訴我們是在17行產生的。
然後我們把代碼修改正確:
1: int _tmain(int argc, _TCHAR* argv[])
2: {
3: int* p = new int;
4: delete p;
5: _CrtDumpMemoryLeaks();
6: return 0;
7: }
運行後,輸出的資訊就是正確的了。
所以在寫代碼的時候除了在產生Dump資訊外,最重要的就是在程式退出的時候需要掉用一次_CrtDumpMemoryLeaks();
假如程式有不止一個出口,那麼我們就需要在多個地方都調用該函數。