[DEBUG]记一次野指针调试

    技术2022-05-20  27

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

    我在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的速度,然后也是不停删除他们。 果然,找到了其实是自己很久前的一次野指针疏忽,导致这么多诡异错误。。。

    总结几点:

    VS提供了堆检查机制,但是它是有限的,比如野指针操作导致内存错乱这种情况,它很难检查到。XP下运行出现run time error,WIN7下运行正常,这是因为WIN7的堆管理要先进一些,野指针导致的错误要难触发一些。囧,网上搜了很久,貌似还没人出现过这种情况。SAFE_DELETE能避免一些野指针错误,但是不要忘了,指针可能赋值在其他地方,你用SAFE_DELETE把指针置0后,其他地方的指针还是野指针。

    最新回复(0)