循環引用指的是使用多個智能指針 shared_ptr 時,出現了指針之間的相互指向,從而形成環的情況,類似於死鎖現象,在這種情況下智能指針往往不能正常調用對象的析構函數,從而造成內存泄漏;
#include<iostream> #include<memory> using namespace std; template<typename T> class Node{ public: Node(const T& value) :_pPre(NULL) , _pNext(NULL) , _value(value) { cout << "Node() " << endl; } ~Node() { cout << "~Node()" << endl; cout << "this: " << this << endl; } shared_ptr<Node<T>> _pPre; shared_ptr<Node<T>> _pNext; T _value; }; void Funtest(){ shared_ptr<Node<int>> sp1(new Node<int>(1)); shared_ptr<Node<int>> sp2(new Node<int>(2)); cout << "sp1.use_count: " << sp1.use_count() << endl; cout << "sp2.use_count: " << sp2.use_count() << endl; sp1->_pNext = sp2; sp2->_pNext = sp1; cout << "sp1.use_count: " << sp1.use_count() << endl; cout << "sp2.use_count: " << sp2.use_count() << endl; } int main(){ Funtest(); return 0; }
shared_ptr 實現中可以得知,當我們知道了引用計數減為零時,析構時才會釋放對象,而上述情況造成了一個僵局,就是當析構對象時先析構 sp2,但是 sp2 的空間 sp1還在使用,所以引用計數為 1,不釋放,sp1 也是同理。這樣就造成了死循環,最后誰也沒釋放,內存泄漏;
在實際編程過程中應該盡量避免出現智能指針之間相互指向的情況,如果避免不了就是用弱指針,weak_ptr 只使用,不增加計數,只要出了作用域就會自動析構。