share_ptr交叉引用导致的内存泄露问题

我们先来看一段代码:

#include<iostream>
using namespace std;

class B;	//声明
class A
{
public:
	shared_ptr<B> pb_;
	~A()
	{
		cout << "A delete\n";
	}
};

class B
{
public:
	shared_ptr<A> pa_;
	~B()
	{
		cout << "B delete\n";
	}
};

void fun()
{
	shared_ptr<B> pb(new B());
	shared_ptr<A> pa(new A());
	cout << pb.use_count() << endl;	//1
	cout << pa.use_count() << endl;	//1
	pb->pa_ = pa;
	pa->pb_ = pb;
	cout << pb.use_count() << endl;	//2
	cout << pa.use_count() << endl;	//2
}

int main()
{
	fun();
	system("pause");
	return 0;
}

输出结果为

1
1
2
2
请按任意键继续. . .

我们可以看到,智能指针share_ptr管理的两个对象并没有被析构,在两个share_ptr对象出现交叉引用时,两个对象的引用计数均为2,而当离开函数fun时,pb,pa对象的引用计数均减1,但二者的引用计数均为减到0,无法触发所管理对象的析构,因此这两个对象的引用计数由于永远无法降为0而永远无法释放,导致内存泄漏。

智能指针weak_ptr可以很好的解决这个问题。
我们可以将两个对象成员中的其中一个智能指针改为weak_ptr就可以了,如,我们把类A里面的shared_ptr pb_,改为weak_ptr pb_

class B;	//声明
class A
{
public:
	weak_ptr<B> pb_;
	~A()
	{
		cout << "A delete\n";
	}
};

class B
{
public:
	shared_ptr<A> pa_;
	~B()
	{
		cout << "B delete\n";
	}
};

void fun()
{
	shared_ptr<B> pb(new B());
	shared_ptr<A> pa(new A());
	cout << pb.use_count() << endl;	//1
	cout << pa.use_count() << endl;	//1
	pb->pa_ = pa;  // pa_是强引用,A对象引用计数加1,为2
	pa->pb_ = pb;  // pb_是弱引用,B对象引用计数不变,为1
	cout << pb.use_count() << endl;	//1  B对象的引用计数
	cout << pa.use_count() << endl;	//2  A对象的引用计数
}

运行结果

1
1
1
2
B delete
A delete
请按任意键继续. . .

在退出fun函数时,pa, pb对象析构,pa,pb的引用计数均减1,pb管理对象的引用计数为0,pa管理对象的引用计数为1,B对象析构,析构时包含的pa_对象被析构,引用计数减1,此时pa_管理对象引用计数为0,A对象析构。

猜你喜欢

转载自blog.csdn.net/qq_31904421/article/details/107708025