最近无聊写了一个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 版权所有,未经许可,不得转载