C裡面沒有垃圾回收機制,有時候你申請了動態內存卻忘記釋放,這就尴尬了(你的程序扮演了強盜角色,有借有還才是好孩子)。當你想找出內存洩露的地方時,有的投入海量的代碼中,頭痛不已。還好GNU C庫提供了些簡單的方法。
mtrace和muntrace兩個函數可以幫助我們追蹤動態內存使用情況。前提是我們設置了MALLOC_TRACE環境變量,改環境變量需要指向我們系統下的一個可寫入的常規文件。做法如下:
MALLOC_TRACE=/your/path/to/file.txt export MALLOC_TRACE
mtrace會為malloc,remalloc和free安裝一些特殊的handlers。這些函數的使用情況都會被記錄在文件中。
muntrace會卸載之前安裝的特殊handlers。也就意味著動態內存追蹤結束。
一般情況下我們在main函數開頭部分調用mtrace,return之前調用muntrace。
這兩個的函數原型在下面給出
#include<mecheck.h> void mtrace(void) void muntrace(void)
使用實例:
#include<mcheck.h>
#include<stdlib.h> int main(int argc, char *argv[]) { #ifdef DEBUG mtrace(); #endif int *a = NULL a = malloc(sizeof(int)); //在這裡我們不調用free函數 return 0; }
在上面的代碼中,我們沒有調用muntrace(),也不推薦使用。原因是在linux C中不僅是你的程序會追蹤動態內存問題,C庫也會使用。如果你調用muntrace(),那就意味著C庫停止追蹤動態內存。
如果你使用宏定義DEBUG編譯文件,執行編譯後的可執行文件,你會發現file.txt裡面有些我們看不懂的東西。這些內容是給機器看的。大多數linux發行版本都帶有mtrace命令(沒錯,名字一樣的)。使用mtrace命令將機讀內容轉化為人讀。使用如下命令:
mtrace a.out file.txt
上述代碼執行該命令後的結果如下
Memory not freed: ----------------------- Address Size Caller 0x092a6378 0x4 at /root/tmp.c:9
很顯然第9行的malloc函數,我們沒有調用相應的free()函數來釋放內存。