这两天碰到了一个bug,表现是这样的:Debug下一切正常,一派祥和之气;Release下暗潮汹涌,很不正常;Release模式编出来的东西,用lua的Decoda调试也乖得很,不出任何问题。这是怎么回事呢?
扫一遍代码,没看出端倪,再扫N遍,还是没有收获;最终还是通过调试找到了问题出在哪里,并解决掉。回头看看,也算是费了很大的劲才搞定。
首先说下问题出在哪里:类中的一个数据成员没有被初始化;其次,说下解决方法:在构造函数的初始化列表中正常初始化。一切就这么简单。
发现问题,解决问题是一方面,而完全搞懂问题,掌握问题则是另一方面。不完全弄清楚前因后果,谁能保证下次你不会犯同样的错误呢?简单解释下原因:
你通过new创建了一个对象,然后销毁,再然后用new创建了一个完全一样的对象。假如这个对象的类中有一个数据成员,既没有被初始化,也没有在析构函数中进行类似清0,复位之类的操作,并且如果你之后new出的对象是建立在原来的内存空间上,那么此刻该成员的值就是你最初创建的对象销毁之前对应的值。更进一步,该值如果在你的程序中占据着很重要的位置,那难免不会出错。
总结看来,release进行了优化,第二次new出的对象,是建立在原对象的内存空间上;而debug和调试模式下,第二次使用的内存空间和第一次的 位置上没必然联系(这个地方说的不够严谨,因为我现在也不清楚这方面的具体细节。望高手指点,有空详细补充上)
说起来总是很抽象,可以看这样一个例子:
class Control { void destroyWorld(){..} void happy() {..} public: int year; Control(){} } Control *ptr1 = new Control; .. ptr1->year = 2012; .. delete ptr1; Control *ptr2 = new Control; .. if((ptr2->year) == 2012) ptr2->destroyWorld(); else ptr->happy();
举例而已,我们不会有这样简单的失误;
另一方面,实际情况要“含蓄”很多很多;
代码不是人,绝不模棱两可,0是0,1是1;
程序员绝对必须要有清晰透彻明朗的感觉;
没看懂上面所有的东西也没关系,但请务必记住这样一句话:养成良好的习惯,对象的所有数据成员,必须进行初始化!