C C 記憶體洩漏檢查之經驗

2021-04-01 01:57:40 字數 2269 閱讀 4273

c程式中最可怕的事情就是碰到記憶體洩漏或者記憶體錯誤,特別是對於大型的專案而言要去查乙個小小的記憶體洩漏可要花不少功夫的。目前已經有很多這方面的工具,比較著名的如rational purify,不過purify對linux的支援比較少,而且有一種洩漏是由於執行過程中不斷增長但是在程式結束的時候釋放的洩漏這些工具有時也無能為力,另外一條路是通過過載new,delete,malloc等來達到記憶體監控的目的,這些方法比較簡單靈活,而且僅用來檢查自己的**部分的錯誤,因此顯得比較有效,不過也存在著自身的一些侷限性,下面逐一介紹:

1、mfc's 過載操作符

這種方法的核心語句是:

#ifdef _debug

#define debug_new new(__file__,__line)

#else

#define debug_new new

#endif

#define new debug_new

但是這種方法使用了new操作符的replacement 操作,因此就要求程式中不能使用replacement操作。但是stl中廣泛的使用了new操作符的replacement方法。

2、巨集替換技巧篇

int __declspec( thread ) this_line;

char __declspec( thread ) this_file[1024];

#define delete (this_line=__line__,strcpy(this_file, __file__),0)? 0 : delete

#define new (this_line=__line__,strcpy(this_file, __file__),0)? 0 : new

這種方法的缺點是this_file和this_line必須使用執行緒區域性變數,而且最鬱悶的事情是它不能夠覆蓋直接呼叫operator new的場合。而且該方法不能使用於gcc編譯器

3、hook alloc

一般的程式記憶體分配都是通過crt呼叫的,而且linux的和window的crt實現都支援malloc hook.對於windows程式是:_crtsetallochook具體用法可以參考msdn。而且windows下面的這個hook無法獲得發分配的記憶體位址,但是每次都有乙個requestid,而且這個hook是同時支援alloc,malloc,realloc,delete的,刪除的時候和分配的時候使用的是同乙個requestid。當發現有記憶體洩漏的時候還需要通過alloc的時候儲存的thread context才能夠通過使用dbghelp.dll來dump出當時的**位置。不過這個方法最大的好處是不但但連malloc,new而且你的程式就算呼叫了別的模組的open函式,裡面呼叫了malloc,而你沒有使用close這樣的記憶體洩漏也能檢查出來,的確非常好用。不過這種方法的致命的缺陷是對於靜態物件無能為力,因為既然是hook總是需要在乙個時間呼叫,如果在此之前就已經分配的記憶體是無法檢測出來了。

linux下面的hook函式是:__malloc_hook等5個函式,另外linux下面需要使用gdb去dunp出**行,這個和windows下面不一樣。windows下面的實現參考stackwalker這個工具,做得非常不錯。而linux下面則是gcc自帶的mtrace,用法如下:

如果你更想讀生(raw)的原始文件, 請參考glibc info的"allocation debugging"一章 (執行info libc); otherwise, you are with me.

glibc提供了乙個檢查記憶體洩漏的方法, 前提是你的程式使用glibc的標準函式分配記憶體(如malloc, alloc...):

1. 在需要記憶體洩漏檢查的**的開始呼叫void mtrace(void) (在mcheck.h中有宣告). mtrace為malloc等函式安裝hook, 用於記錄記憶體分配資訊.在需要記憶體洩漏檢查的**的結束呼叫void muntrace(void).

注意: 一般情況下不要呼叫muntrace, 而讓程式自然結束. 因為可能有些釋放記憶體**要到muntrace之後才執行.

2. 用debug模式編譯被檢查**(-g或-ggdb)

3. 設定環境變數malloc_trace為一檔名, 這一檔案將存有記憶體分配資訊.

4. 執行被檢查程式, 直至結束或muntrace被呼叫.

5. 用mtrace命令解析記憶體分配log檔案($malloc_trace)

(mtrace foo $malloc_trace, where foo is the executible name) 如果有記憶體洩漏, mtrace會輸出分配洩漏記憶體的**位置,以及分配數量.

可惜的是目前的mtrace只能解析gcc編譯出來的行數,如果是g++編譯出來的它就不行了……

記憶體洩漏檢查

1.乙個指標多次進行賦值時,每次賦值後使用完後要釋放記憶體 coffsetcoedgemap poffsetcoedgemap polygonoffset ppoly,retpolygon,doffsetdis,enextend,0.1 expect true g ovldmgr.isvalid r...

記憶體洩漏檢查

關於記憶體洩漏的檢查網上有很多的例子和 其基本的方法都是用巨集,替換掉記憶體分配以及釋放的函式。但是現在網上很多的例子中沒有乙個是適合我們公司的需求的。具體的對記憶體洩漏檢查有如下要求 1.記憶體洩漏檢查的 盡可能少的占用cpu及記憶體 2.盡可能的不影響原程式 因為,我們的伺服器程式有洩漏而且是特...

SPDisposeCheck記憶體洩漏檢查工具的使用

spdisposecheck是開發sharepoint專案必不可少的工具之一,用它可以檢測出我們寫的 是否正確銷毀掉諸如spsite或者spweb之類的 資源消耗大戶 你開啟乙個spsite或者spweb物件 將占用1m到2m的記憶體,如果你不斷開啟此類物件並沒有及時關閉,那麼你的記憶體就會很快被消...