記憶體洩露和資源洩露是c\c++程式設計師不得不面對的乙個問題,隨著程式越來越大,稍不留神就可能在程式中留下了記憶體洩露的隱患,這個問題很多人可能覺得沒什麼,就洩**記憶體而已,只要程式邏輯沒問題,但是如果程式執行時間很長或者洩露的記憶體很大的話,會導致系統資源占用過多,嚴重的也可能使得程式崩潰。
前段時間為了分析程式中是否存在記憶體洩露問題,使用了devpartner工具來進行分析,但是該工具要對程式進行重新裝載,插入很多的監測**,導致程式執行速度相當慢,效率也很低,一次執行下來就得個幾天時間,而且也只能對作業系統管理的記憶體來進行分析,但是如果是自己申請的一大塊記憶體堆中發生了記憶體洩露的話,工具也沒辦法查出來了。
於是準備自己弄乙個記憶體監測的,其實蠻簡單的東西,在封裝的記憶體申請函式中插入**來儲存分配的指標和大小,在釋放的地方則把這個指標刪除掉,最後沒有被刪除掉的指標則是可能存在記憶體洩露的地方了,但是目前為止只能判斷是否發生了記憶體洩露,接下來就是要把發生記憶體洩露時刻的呼叫堆疊列印出來,這樣才能方便的跟蹤問題到底發生在**。
像vc、gdb,都提供除錯過程中列印呼叫堆疊、變數值等功能,例如vc設定為debug模式的話,則會生成乙個pdb的檔案,這是程式資料庫,儲存著除錯和專案狀態資訊,既然vc可以得到除錯資訊的話,那麼從技術角度上來說的話,應該可以程式設計來實現得到除錯資訊的。
接下來首先實現windows下面的獲取呼叫堆疊,查詢msdn,有乙個stackwalk64函式可以獲取堆疊的內容,具體的引數可以檢視msdn,裡面有乙個主要的輸入輸出引數就是lpstackframe64 stackframe,stackframe64結構表示了堆疊中的乙個frame,首先需要對該引數進行初始化,也就是首先要獲得當前函式堆疊的一些資訊,我們知道函式呼叫的時候,會首先儲存呼叫點的一些資訊,從而在函式結束的時候可以返回到呼叫處繼續執行,通過一小段彙編**,我們可以很容易得到函式堆疊中的一些基本資訊,利用這些資訊初始化stackframe引數,然後呼叫stackwalk64函式,該函式就會將函式位址的偏移量記錄下來,接下來就是要將這些偏移量轉換為實際的函式名、檔名、行號等資訊,windows api提供了另外兩個函式symgetlinefromaddr,symgetsymfromaddr。前乙個函式通過偏移量得到函式所在檔案及行號,後面乙個函式通過偏移量得到函式的實際名稱,stackwalk64函式每次呼叫完後會自動的設定frame引數,下次再呼叫則得到的是上一層的函式資訊,以此類推,通過判斷frame的返回函式位址偏移量是否為0則可以用來判斷堆疊結束。
在windows下我們可能需要手動新增某些**到分配和釋放記憶體的地方,感覺更加智慧型化一點的話應該可以使用鉤子來實現。
linux下獲取呼叫堆疊相比而言更加簡單,有個backtrace函式和backtrace_symbols函式,一次就搞定了。
記憶體洩露檢測
c 中檢測記憶體洩漏可以引入系統定義的巨集來檢視,內存在哪個位置洩漏 檔案開始處加入下列定義 define crtdbg map alloc include include 程式退出時加入以下函式 crtdumpmemoryleaks 如果有洩漏會顯示 記憶體洩漏是程式設計中常常見到的乙個問題,我所...
檢測記憶體洩露
程式結束時,作業系統會 程式占用的資源.但是,只要程式還在執行,如果不進行清理,資源最終可能被耗盡.1.vc記憶體洩露檢查工具 visual leak detector 現在已知的最新有2.0版本的,使方法不詳。使用 visual leak detector 2.2.3 在vs工程的linker i...
記憶體洩露檢測
1 包含標頭檔案 include include 2 每個cpp檔案包含 static char this file file define new new normal block,this file,line 3 設定標誌 int tmpdbgflag tmpdbgflag crtsetdbgf...