循环引用变量Linux,智能指针的循环引用与解决

智能指针的循环引用

class Node

{

public:

shared_ptr left;

shared_ptr right;

Node(int v)

{

this->value = v;

cout << "Constructor" << endl;

}

~Node()

{

cout << "Destructor" << endl;

}

private:

int value;

};

int main()

{

shared_ptr root = std::make_shared(4);

root->left = std::make_shared(2);

root->right = std::make_shared(3);

return 0;

}

上面的程序不会有问题,调用三次构造函数,三次析构函数。

下面增加一个指向父节点的指针。

class Node

{

public:

shared_ptr left;

shared_ptr right;

shared_ptr parent;

Node(int v)

{

this->value = v;

cout << "Constructor" << endl;

}

~Node()

{

cout << "Destructor" << endl;

}

private:

int value;

};

int main()

{

shared_ptr root = std::make_shared(4);

root->left = std::make_shared(2);

root->left->parent = root; //强引用计数加1

root->right = std::make_shared(3);

root->right->parent = root; //强引用计数加1

cout << "root reference count = " << root.use_count() << endl;

cout << "left reference count = " << root->left.use_count() << endl;

cout << "right reference count = " << root->right.use_count() << endl;

return 0;

}

调用了三次构造函数,但是没用调用析构函数,这就导致了内存泄漏。

shared_ptr的循环引用定义:

当两个对象(主体是对象)使用shared_ptr相互引用时,那么当超出范围时,都不会删除内存。发生这种情况的原因是shared_ptr在其析构函数中递减关联内存的引用计数后,检查count是否为0,如果不为0,析构函数就不会释放相应的内存。当出现了循环引用后,就会发现count的值总是不为0。

这里我用goodnotes画了两张图,希望能把这个过程解释清楚:

7ae45ae566694e62adabd51b7a58d099.png

c7e54acc014fa6db0af675e9a13eeece.png

那么如何解决这个问题?

使用weak_ptr。

下面使用weak_ptr改进二叉树。weak_ptr不会导致强引用计数增加。

class Node

{

public:

shared_ptr left;

shared_ptr right;

//shared_ptr parent;

weak_ptr parent;

Node(int v)

{

this->value = v;

cout << "Constructor" << endl;

}

~Node()

{

cout << "Destructor" << endl;

}

private:

int value;

};

int main()

{

shared_ptr root = std::make_shared(4);

root->left = std::make_shared(2);

root->left->parent = root; //强引用计数加1

root->right = std::make_shared(3);

root->right->parent = root; //强引用计数加1

cout << "root reference count = " << root.use_count() << endl;

cout << "left reference count = " << root->left.use_count() << endl;

cout << "right reference count = " << root->right.use_count() << endl;

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值