[DEBUG]記一次野指針調試

關於野指針,我覺得最可怕的情況就是,它在程序大部分時候都不會出錯,當你項目越來越大的時候,可能就會出現各種隨機性詭異錯誤了,而這時你壓根就不會想到是自己很久前的一次疏忽。

我在shero裏用的實體框架是這樣的,邏輯對象爲Entity,視覺對象爲Visual,Visual根據Entity來渲染自己,所以它保存了一個Entity指針m_pEntity。

更新流程是:

Entity->Update();

Visual->Update();

當Entity需要刪除時,將m_canDel置爲true。

所以在EntityManager的更新裏就是這樣:

if (m_canDel)  delete pEntity;

但是Viusual怎麼辦呢,Entity沒有保存Visual指針,沒法通知它需要刪除,所以我是這樣更新的:

if(m_pEntity->CanDel())  delete pVisual;

倒黴的是,當m_pEntity爲野指針後,m_pEntity->CanDel()還真爲true。。所以一直沒發覺。


 

DEBUG就是這樣,源頭找到後就會覺得很簡單,如果就這樣自大的一笑了之,那以後肯定繼續被它虐。所以重要的還是對過程的一些反思:

首先,我這種情況就會產生一些隨機性詭異錯誤,而且源頭是在其他模塊裏,比如這個BUG很早以來就一直存在,而且很早前我也發現過一個由於它導致的堆損壞。當時我查到的源頭是在Audio模塊裏,而且只是某個怪物的音效纔會出錯。所以,我當時的結論是:嗯,這個怪物的音效文件有誤,以後給它換過就沒問題了。

後來,又是CEGUI出錯,而且這次不是提示堆損壞,直接run time error指針錯誤。鬱悶,換回WIN7,運行居然一切正常,懷疑又是哪裏的庫版本不對,想半天沒有結果。

又蛋疼的持續2天調試一些根本沒有問題的模塊。後來,採用註釋法把這些出錯的模塊註釋掉,回到了很久前的一個遊戲結構。再採用極限法,加大產生Entity的速度,然後也是不停刪除他們。 果然,找到了其實是自己很久前的一次野指針疏忽,導致這麼多詭異錯誤。。。

總結幾點:

  1. VS提供了堆檢查機制,但是它是有限的,比如野指針操作導致內存錯亂這種情況,它很難檢查到。
  2. XP下運行出現run time error,WIN7下運行正常,這是因爲WIN7的堆管理要先進一些,野指針導致的錯誤要難觸發一些。囧,網上搜了很久,貌似還沒人出現過這種情況。
  3. SAFE_DELETE能避免一些野指針錯誤,但是不要忘了,指針可能賦值在其他地方,你用SAFE_DELETE把指針置0後,其他地方的指針還是野指針。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章