循環(huán)引用-智能指針的死穴之一
來源:程序員人生 發(fā)布時間:2015-04-20 08:09:23 閱讀次數(shù):3267次
智能指針的實現(xiàn)思路也體現(xiàn)了C++基于對象的原則,對象應(yīng)當(dāng)為自己管理的資源負(fù)責(zé),包括資源的分配與釋放,而且最好將資源的釋放與分配弄的自動化1點,典型的實現(xiàn)方法就是在構(gòu)造函數(shù)里分配資源,在析構(gòu)函數(shù)里釋放資源,這樣當(dāng)其他程序員在使用這個對象時,該對象的資源問題幾近不用額外的操心,即優(yōu)雅又方便
然后如此完善的東西,也有其不容忽視的地方,直接上代碼:
// 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();//查看內(nèi)存狀態(tài)
while(count--)
{
//new出來的A的援用計數(shù)此時為1
shared_ptr<A> a(new A);
//new出來的A的援用計數(shù)此時為1
shared_ptr<B> b(new B);
//B的援用計數(shù)增加為2
a->SetB(b);
//A的援用計數(shù)增加為2
b->SetA(a);
}
getchar();//查看內(nèi)存狀態(tài)
//b先出作用域,B的援用計數(shù)減少為1,不為0,所以堆上的B空間沒有被釋放,
//且B持有的A也沒有機(jī)會被析構(gòu),A的援用計數(shù)也完全沒減少
//a后出作用域,同理A的援用計數(shù)減少為1,不為0,所以堆上A的空間也沒有被釋放
return 0;
}
兩次查看內(nèi)存資源狀態(tài)結(jié)果


結(jié)果可知:內(nèi)存增加了幾近20M,更何況我定義的兩個對象本身不怎樣占資源,如果內(nèi)部保護(hù)了幾個list,結(jié)果可想而知!
A和B都相互指著對方吼,“放開我的援用!“,“你先發(fā)我的我就放你的!”,因而悲劇產(chǎn)生了。
所以在使用基于援用計數(shù)的智能指針時,要特別謹(jǐn)慎循環(huán)援用帶來的內(nèi)存泄漏,循環(huán)援用不只是兩方的情況,只要援用鏈成環(huán)都會出現(xiàn)問題。固然循環(huán)援用本身就說明設(shè)計上可能存在1些問題,如果特殊緣由不能不使用循環(huán)援用,那可讓援用鏈上的1方持用普通指針(或弱智能指針weak_ptr)便可.
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈