一个有趣的Bug修正记

来源:互联网 发布:深入体验java项目开发 编辑:程序博客网 时间:2024/05/13 05:15

 最近无聊写了一个Managed类用来托管指针(C++中)。代码如下:(不存在内存泄露)

这个类有个很严重的问题,就是使用链表的时候。比如有如下的链表定义:

这是一个很一般的链表节点结构。下面,我们使用这个结构:

这个看起来是没什么问题,但是运行的时候有Access Violation。前后加入调试语句之后,发现问题出现在:

p = p->next; (在输出那段里面)

这个有什么问题呢?好像是对象已经被回收了。神奇啊!看看Managed的代码。

在“=运算符”中,有个很大的问题:

问题出现在“this->~Managed();”这里。经过一番思考和画图后,发现p = p->next;的执行方式如下:

p.operator = (p.operator->()->next);

调用operator->没问题。

调用operator=:

调用析构函数

析构对象(p的当前对象)

之前,head=NULL,已经回收了head(head这里是一个无效数据),所以p的引用计数为0,回收p托管的对象。

回收p托管的对象之后,p托管的对象的next的引用计数也变成0,顺便也回收了,就这样,把后面的节点都回收了……

析构完毕

p托管了不可用内存(有的人称为“野指针”“悬空指针”“悬垂指针”)。

结束调用operator=。

 

然后下一轮循环的时候,就出现了Access Violation。

 

 

于是,代码改为使用备份:

 

至此,问题解决。希望本文能给广大Developer一些Debug的帮助!

 

 

by Logic 版权所有,未经许可,不得转载

原创粉丝点击