一、问题描述
在使用shared_ptr
时,如果出现了循环引用(如链表节点的next
指向),就会导致内存泄漏。
例如以下两个类,内部互相有一个指向对方的智能指针,在生存空间结束后就不会被释放掉:
#include <iostream>
#include <memory>
using namespace std;
class CTestB;
class CTestA {
public:
shared_ptr<CTestB> b;
CTestA() {
cout << "CTestA()" << endl;
}
~CTestA() {
cout << "~CTestA()" << endl;
}
};
class CTestB {
public:
shared_ptr<CTestA> a;
CTestB() {
cout << "CTestB()" << endl;
}
~CTestB() {
cout << "~CTestB()" << endl;
}
};
int main() {
shared_ptr<CTestA> a(new CTestA);
shared_ptr<CTestB> b(new CTestB);
cout << "a.use_count = " << a.use_count() << endl;
cout << "b.use_count = " << b.use_count() << endl;
a->b = b;
b->a = a;
cout << "a.use_count = " << a.use_count() << endl;
cout << "b.use_count = " << b.use_count() << endl;
return 0;
}
编译后的运行程序的结果:
原因很简单,a->b = b
导致b的引用计数增加,b->a = a
导致a的引用计数增加,在程序运行完后,a、b自行析构引用计数都会减一,但是此时引用计数都是1,因此不会释放。
二、解决方法
shared_ptr
循环引用要通过weak_ptr
来解决,weak_ptr
也是智能指针的一种,不过它是一种弱引用,不会增加智能指针的引用计数。
分别修改两个类为以下形式:
class CTestA {
public:
weak_ptr<CTestB> b;
// ...
}
class CTestB {
public:
weak_ptr<CTestA> a;
// ...
}
运行结果:
此处评论已关闭