智能指针
因为c++没有自动的内存回收机制,所以程序员每次在new一个对象的时候都需要手动delete,但是有的时候会忘记delete,或者因为程序分支等原因delete没有执行,就会使得对象没有释放而导致内存泄漏。
智能指针(shared_ptr)是一个类,存储了指向一个对象的指针,通过引用计数的方式记录有多少个智能指针对象共享同一个指针,它在指针没有被使用时会自动释放其内存。
引用计数
每次创建智能指针对象时,初始化其指针,引用计数设为1;
当智能指针对象成为另一个智能指针对象的副本时,执行拷贝构造函数,并将引用计数加1;
当执行赋值语句时,左操作数的引用计数减1,右操作数的引用计数加1;
当执行析构函数时,引用计数减1;
当引用计数为0时,释放内部指针指向的对象的空间。
循环引用
智能指针存在的一个经典问题就是循环引用问题,如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include<iostream> #include<memory> using namespace std; template<class T> struct Node { Node(T data = T()) :_data(data), Pnext(NULL), Ppre(NULL) { } ~Node() { cout << "Call ~Node()" << endl; } shared_ptr<Node> Pnext; shared_ptr<Node> Ppre; T _data; };
void testShared_Ptr() { shared_ptr<Node<int>>sp1(new Node<int>(1)); shared_ptr<Node<int>>sp2(new Node<int>(2)); cout << sp1.use_count() << endl; cout << sp2.use_count() << endl; sp1->Pnext = sp2; sp2->Ppre = sp1; cout << sp1.use_count() << endl; cout << sp2.use_count() << endl;
} int main() { testShared_Ptr(); cout<<"testShared_pte()函数运行结束"<<endl; system("pause"); return 0; }
|
在函数testShared_Ptr执行完之后,会先释放sp2,所以sp2的引用计数减1变为1,然后释放sp1的内存,sp1的引用计数也减1变为1。因为sp1中有对sp2的指针,sp2中也有sp1的指针,所以导致二者的引用计数都没有办法变为0,于是导致二者的内存空间都不会释放。