智能指针--循环引用
主讲人:hai.
时间:2010-10-9
引起智能指针循环引用的原因:
一、自身循环引用
class A
{
private:
MySmartPtr<A> ptr;
public:
voidhold( const MySmartPtr<A> &other){ptr = other;}
};
int main()
{
{
MySmartPtr<A>ptrA(new A); (1)
ptrA->hold( ptrA ); (2)
}
_CrtDumpMemoryLeaks(); //将会检测到new的资源没有释放掉
return0;
}
其中,MySmartPtr<A> 是一个计数式的智能指针。
内存分布:
所以很显然构成了一个环。
当执行2语句的时候,由于智能指针给自身赋值了,所以引用计数将增加到2,但实际的享有资源A的对象只有一个,所以当智能指针离开作用域的时候,智能指针的引用计数只降到1,所以,new的资源A将不会释放。同理可以应用于多个智能指针间的循环引用问题。
二、多个智能指针间的循环引用
class B;
class A
{
private:
MySmartPtr<B> ptrB;
public:
//…………..
voidhold( const MySmartPtr<B> &other ){
ptrB = other;
}
};
class B
{
private:
boost::shared_ptr<A> ptrA;
public:
// ……………….
voidhold( const boost::shared_ptr<A>&other ){ptrA = other;}
};
int main()
{
{
MySmartPtr<B> ptrB(new B);
boost::shared_ptr<A>ptrA(new A);
ptrA->hold( ptrB );
ptrB->hold( ptrA );
}
_CrtDumpMemoryLeaks(); //将会检测到new的资源没有释放掉
return0;
}
其中,shared_ptr是boost库里的非侵入式的计数式智能指针。
内存布局
很显然,也构成了一个环。
三、解决方法。
1、可用另一个辅助的智能指针检测是否存在智能指针。例如boost库中针对shared_ptr智能指针的weak_ptr。
2、从设计上解决(根本方法)