您的位置:首页 > 其它

由一个BUG想到的

2009-08-08 21:57 253 查看
一个应用程序时不时出现一些莫名其妙的错误。这些错误不是致命的,也就一直推迟,没有修补该bug。

后来,终于发现该bug的规律,就是在加载某个资源的时候,可能产生错误的现象:1、内存访问错误,程序直接崩溃。2、有一个按钮,位置显示错误。由于找到规律,修改bug就容易多了。找到加载资源的代码,终于发现我把一个对象指针,用作了对象数组指针,意思就是:

class A{};

A *pa; pa = new A;

A *pas; pas = new A[3];

由于打字错误,我使用了pa[2] = ...。编译时没问题的,但可想而知,这完全就是内存越界访问错误。

对pa[2]的访问,如果pa[2]指向内存不是本进程空间,则会访问越界,导致程序崩溃,也就产生上面的现象1。如果指向的是本进程空间,则会访问到堆中别的对象,也就导致现象2发生。

这就体现了指针“不好用”之处。一个指针既可以指向一个对象,还可以指向对象数组。

为什么会发生这个错误呢?首先原因就是我打字错误,跟准确的来说,是AssistX提示时,我没看清楚,点击太快所造成的。这也说明有时候用辅助工具不一定就是好事。

还有一个原因就是我的编程习惯的问题。为了解耦,我大量使用指针,比如,class A拥有一个变量B,一般这么声明:

#include "B.h"

class A{

private:

B m_b;

};

这段代码的声明,有较高的耦合度。因为客户程序如果想使用A,也必须把B的头文件包含进来。所以一般的处理方法是:

class B;

class A{

private:

B* m_pb;

};

这段代码具有较低的耦合度,但导致A的实现文件必须动态创建B对象。

我的代码习惯选择了后者,就需要维护好指针。由于我的疏忽,导致了文章开头所说的bug。

上面两种代码编写方式到底哪个好呢?我还是坚持后者,但也不要过于追求解耦。当初我的代码就是过于追求解耦。其实,对于公共的、库函数等公用的类,就没必要这么声明,而直接使用方式一声明就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: