[DEBUG]记一次野指针调试

来源:互联网 发布:未始知西山之怪特 编辑:程序博客网 时间:2024/05/22 11:33

关于野指针,我觉得最可怕的情况就是,它在程序大部分时候都不会出错,当你项目越来越大的时候,可能就会出现各种随机性诡异错误了,而这时你压根就不会想到是自己很久前的一次疏忽。

我在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后,其他地方的指针还是野指针。