[DEBUG]內存泄露調試

呼。。又是一次痛苦的調試經歷,趕緊記點心得吧。雖然是一個很傻X的失誤,但是經歷的過程還是收穫蠻多的。開始之前,順便透露一下,關於shero,我已經決定做一個單機開源RPG了,最遲在5月發佈吧,最終效果相信不會令大家失望。。:)

好了,起因是這樣的,因爲集成了CEGUI,界面基本搭好時,卻發現有嚴重的內存泄露,至少當時我是這樣認爲的,然後便開始嘗試各種辦法,沒有結果。其實最後才發現,原因很簡單,我自己的項目里加入了這個設置:

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_EVERY_1024_DF | _CRTDBG_CHECK_CRT_DF);

_CRTDBG_DELAY_FREE_MEM_DF,我傻B了,英語白學了。在加入CEGUI以前,項目的每輪循環裏不會都有new 與 delete的操作,自然看不出啥問題,但是有了CEGUI後就不一樣了,new分配的空間是延遲釋放的,不斷堆積後看上去肯定就是嚴重的內存泄露了!


上面的不是重點,重點是過程中的一點調試心得,簡單記錄下吧:

1,關於內存泄露檢測,VC環境下可以檢測的,http://shallway.net/blog/?p=337這裏的DEBUG_NEW有提到。

但是,這種方法不能解決2個問題:

  1. 如果內存泄露是在附加庫或者Dll中,調試輸出窗口顯示的信息不包括源文件地址
  2. 通常更詭異的內存泄露是這樣的:程序運行中不斷積累,程序退出時卻會一起釋放的,這種情況是檢測不出的。

對於1,一個很有用的技巧是,調試輸出窗口不會顯示源文件地址,但是會顯示這個未分配Block的ID,知道這個ID後,在程序中加入_CrtSetBreakAlloc(ID),再運行程序,就會在分配這個BLock時中斷,這樣調試就有堆棧輸出窗口了,這樣就可以知道是附加模塊哪裏的問題了。

對於2,除開其他調試技巧,其實用1的辦法也會有幫助,那就是在_CrtSetBreakAlloc(ID)裏,不斷更改ID值,視具體情況,達到對問題根源的準確定位。

 

2,關於Release下運行出現指針訪問錯誤,Debug下卻沒問題的可能原因:

  1. 檢查DEBUG下所有warning
  2. 某些函數不是每個路徑都有返回值
  3. 對象構造函數裏不是對每個成員變量都做了初始化(這個最有可能)

也可能有其他原因,以後再整理。OVER。

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