循环引用-智能指针的死穴之一
来源:程序员人生 发布时间:2015-04-20 08:09:23 阅读次数:3050次
智能指针的实现思路也体现了C++基于对象的原则,对象应当为自己管理的资源负责,包括资源的分配与释放,而且最好将资源的释放与分配弄的自动化1点,典型的实现方法就是在构造函数里分配资源,在析构函数里释放资源,这样当其他程序员在使用这个对象时,该对象的资源问题几近不用额外的操心,即优雅又方便
然后如此完善的东西,也有其不容忽视的地方,直接上代码:
// share_ptr.cpp : 定义控制台利用程序的入口点。
//
#include "stdafx.h"
#include "common_class.h"
class B;
class A{
private:
typedef tr1::shared_ptr<B> Item_Type;
public:
explicit A(){};
virtual ~A(){};
public:
void SetB(const Item_Type ptr_B){m_B = ptr_B;}
private:
Item_Type m_B;
};
class B{
private:
typedef tr1::shared_ptr<A> Item_Type;
public:
explicit B(){};
virtual ~B(){};
public:
void SetA(const Item_Type ptr_A){m_A = ptr_A;}
private:
Item_Type m_A;
};
int _tmain(int argc, _TCHAR* argv[])
{
size_t count = 100000;
getchar();//查看内存状态
while(count--)
{
//new出来的A的援用计数此时为1
shared_ptr<A> a(new A);
//new出来的A的援用计数此时为1
shared_ptr<B> b(new B);
//B的援用计数增加为2
a->SetB(b);
//A的援用计数增加为2
b->SetA(a);
}
getchar();//查看内存状态
//b先出作用域,B的援用计数减少为1,不为0,所以堆上的B空间没有被释放,
//且B持有的A也没有机会被析构,A的援用计数也完全没减少
//a后出作用域,同理A的援用计数减少为1,不为0,所以堆上A的空间也没有被释放
return 0;
}
两次查看内存资源状态结果
结果可知:内存增加了几近20M,更何况我定义的两个对象本身不怎样占资源,如果内部保护了几个list,结果可想而知!
A和B都相互指着对方吼,“放开我的援用!“,“你先发我的我就放你的!”,因而悲剧产生了。
所以在使用基于援用计数的智能指针时,要特别谨慎循环援用带来的内存泄漏,循环援用不只是两方的情况,只要援用链成环都会出现问题。固然循环援用本身就说明设计上可能存在1些问题,如果特殊缘由不能不使用循环援用,那可让援用链上的1方持用普通指针(或弱智能指针weak_ptr)便可.
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠