0%

智能指针

智能指针

因为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;//1
cout << sp2.use_count() << endl;//1
sp1->Pnext = sp2;
sp2->Ppre = sp1;
cout << sp1.use_count() << endl;//2
cout << sp2.use_count() << endl;//2

/*Node<int> *a = new Node<int>(3);
delete a;
shared_ptr<Node<int>> c(new Node<int>(4));*/

}
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,于是导致二者的内存空间都不会释放。

Welcome to my other publishing channels