Re: [問題] 如何確認是否 free 對記憶體

看板C_and_CPP作者 (閉上眼的魚)時間11年前 (2012/11/02 01:34), 編輯推噓2(202)
留言4則, 2人參與, 最新討論串2/2 (看更多)
※ 引述《Linux (Windows)》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) : DEV C++ : 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) : #include "stdio.h" : #include "stdlib.h" : #include "string.h" 以下恕刪。由於原 po 所用的看起來較像是 C library,所以這方法應該還是可行的。 原理和詳細實作說明在 http://ppt.cc/aoSW section 8, 由於原文落落長 (加上裡面的 src 有點 bug 沒修正,下面的附檔已修正) 這裡只簡述。 --------- 首先實作, malloc / realloc memory leak 原理大多是用 link-list (簡單用單向,要效能好一點做雙向,個人是覺得差別不會太大) 概念是將 malloc / realloc / free 重新定義成 dbg_malloc / dbg_realloc / dbg_free , 自己再去實作 dbg_xxxx 函式, dbg_xxxx 函式會在每次 malloc 時加入 link-list, 中間會加入一些額外資訊,如 __FUNC__(這個非標準我就沒寫入了)、 __LINE__、__FILE__、malloc 所得位址、malloc byte 數 等。 每次 free 時從 link-list 裡找 address並刪除, 如果在 link-list 裡面所不到其位址,就代表刪除失誤。 最後「程式結束」的時候, 再用一個 dbg_dump_report 之類的函式,把該 link-list 所有剩下的 node 資訊 列印出來,那些就是 memory leak 的部份。 不過是 C++ 的話,這問題可能就沒那麼簡單了, 要測 new operator 造成之 memory leak 可能要從底層 API 抓起, 目前我還沒辦法抓到由 new 所造成之 memory leak。 ---------- 有篇文章講得很好,#1FWIgryW (Programming)作者 purpose , 裡面講了不少細節部份,有空可以去看看。 ---------- 另外小弟有開發一份簡易之 dbg_malloc / dbg_free , 省略了很多問題 (像是 alignment 沒處理), dbg_realloc / dbg_calloc 也沒實作, 但現在 google "dbg_malloc" 就是突然找不到之前的 reference source, 或許您可再花些時間往這方面找。 範例及原始碼如連結 http://ppt.cc/m7JD 裡面的 leak.rar 下載下來便是 (使用的 IDE 是 Code::Blocks,可以自己轉到 Dev-C++ 測試 ) (其中的 leak.c 是一份資料結構 link 故意寫成 memory leak 的範例 ) 使用方法很簡單,步驟如下 (0) 將 "dbg_malloc.h" "dbg_malloc.c" "my_malloc.h" "my_malloc.c" 加入專案 (1) 在「要查」memory leak 的檔案裡 (所以有 n 個檔案要查的話都要做), 最前面加入 #define DBG_MALLOC #include "dbg_malloc.h" (2) 其它的都正常使用 (3) 最後程式 (main 函式) 結束前,呼叫 dbg_report(); 裡面的範例結果如下 4 3 2 1 0 [001] D:\Setting\win7_desktop2\....\leak.c: 37 address : 0x005B0F90 size : 8 value : 24 40 40 00 25 00 00 00 就抓到 leak.c 裡面第 37 行有 leak,你可以再拿你的 code 進來試試是否正常。 ----------- 當然我必須強調,這份是非常初始的 code, 除了提供指令少,還沒考慮多行緒問題、沒考慮 alignment 問題、 沒像 vc 可以偵錯到 heap array 逾界問題,只有單純的兩個指令。 windows 下沒有神器 valgrind,compiler 不是 VC ,大概只能這麼搞而已, 或許在您 google 到較好的 "dbg_malloc" 前,或許這份 code 可供應急便是。 當然有找到更好的話 (這個要全部寫完整真的是要人命),也請告知我一聲。 ------ 補充另一個選擇 : DrMemory http://code.google.com/p/drmemory/ -> downloads -> DrMemory-Windows-1.5.0-5.exe 這個程式蠻妙的,不過是針對 exe 做記憶體除錯, 安裝的時候記得選擇環境變數一起註冊。 假設生成之執行檔是 D:\a.exe,開啟命令提示字元後, 輸入 DrMemory.exe D:\a.exe,最後會跳出一份 results.txt, 大概如下 Error #1: LEAK 8 direct bytes 0x00371218-0x00371220 + 0 indirect bytes # 0 PushFront # 1 main ERRORS FOUND: 0 unique, 0 total unaddressable access(es) .... 1 unique, 1 total, 8 byte(s) of leak(s) 0 unique, 0 total, 0 byte(s) of possible leak(s) ... 代表呼叫順序 main->PushFront, 在 PushFront 函式裡面記憶體有誤, 至於掛在哪的話.. 嗯,還是要回去用人工 trace。 其它的參數可以直接在 cmd 下輸入 DrMemory.exe 查看更多參數。 手邊的 note ,其它 windows 底下查 memory 錯誤的軟體還有 purifty、Insure++,應該是還有更多,只是自己必須再花點時間去找、去學怎麼用便是. 以上,有誤請指導,source 有 bug (改過兩次就是了)歡迎回報,謝謝收聽。 -- 就算把新鮮的肝拿回去,還是一樣寫碼到禿頭,加班到天亮。 你是不是想這麼做?是的話你就拿回去~ 拿啊!! 九世宅男 : 下輩子不要再讓我幹工程師了 ~ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.76.161 ※ 編輯: EdisonX 來自: 180.177.76.161 (11/02 02:24)

11/02 15:00, , 1F
好寫實的簽名檔.......
11/02 15:00, 1F

11/03 01:24, , 2F
可以用CRT Library並重定義new
11/03 01:24, 2F

11/03 01:31, , 4F
sorry, 沒注意到開發平台= =
11/03 01:31, 4F
文章代碼(AID): #1GahAdL6 (C_and_CPP)
文章代碼(AID): #1GahAdL6 (C_and_CPP)