日常隨手記,記錄一些瑣碎的技術細節

本文用作日常隨手記,平時遇到一些瑣碎的技術細節就隨便扔進來備查。必要時也可整理成獨立博文發表。

通過 _CrtSetBreakAlloc 定位內存泄漏點

現象:Visual Studio 調試運行程序結束後在輸出欄提示有內存泄漏,內容如下

Detected memory leaks!
Dumping objects ->
{5481} normal block at 0x01371820, 11648 bytes long.
Data: < > 0C F2 B7 00 0A 00 00 00 CD CD CD CD CD CD CD CD
Object dump complete.

然而它並未具體指出泄漏點在哪裏,很難複查。我看到這裏直接麻爪了。

解決:在 main 函數開始處添加一行代碼 _CrtSetBreakAlloc(5481);,再次調試運行,IDE會自動在該內存塊被申請時中斷下來,程序員通過調用堆棧(CallStack)可以很容易的定位內存泄漏點。看到這個結果我當時很驚喜。

注意,調用 _CrtSetBreakAlloc 時傳入的參數就是之前IDE報告的內存泄漏序號:

{5481} normal block at 0x01371820, 11648 bytes long.

_CrtSetBreakAlloc(5481);

原理:在調試模式下,malloc/free等函數調用被替換品取代,記錄每一次內存分配和釋放動作,併爲新分配的內存塊順序編號(從1到N),到程序退出時將未被釋放的內存塊編號打印出來。後來代碼加上 _CrtSetBreakAlloc(N) 調用再次編譯運行並不影響內存分配釋放順序,只要程序執行流程不變,本輪第N次內存分配跟上次運行的第N次內存分配是同一個調用點。

給Visaul Studio的建議:其實可以事先記錄內存分配調用點的文件名和行號並在檢測到泄漏時第一時間報告出來,同時提示用戶藉助 _CrtSetBreakAlloc 追蹤調用棧。

20181129

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章