【C++进阶】智能指针

为什么需要智能指针?

我们先来看一段代码:
在这里插入图片描述

大家觉得这段代码有什么问题?
发生了,内存泄漏。
在这里插入图片描述

因为p1,p2,p3指向的空间没有释放掉导致的。这就是异常安全问题。那要怎么解决呢?我们下面再回答。

内存泄漏

什么是内存泄漏,内存泄漏的危害

在这里插入图片描述
在这里插入图片描述

内存泄漏分类(了解)

  • 堆内存泄漏(Heap leak)
    堆内存指的是程序执行中依据须要分配通过malloc / calloc / realloc / new等从堆中分配的一块内存,用完后必须通过调用相应的 free或者delete 删掉假设程序的设计错误导致这部分内存没有被释放,那么以后这部分空间将无法再被使用,就会产生Heap Leak
  • 系统资源泄漏
    程序使用系统分配的资源比方套接字、文件描述符、管道等没有使用对应的函数释放掉,导致系统资源的浪费,严重可导致系统效能减少,系统执行不稳定

如何避免内存泄漏

在这里插入图片描述

智能指针的使用及原理

在这里插入图片描述

smart_ptr

在这里插入图片描述
那么smart_ptr能解决上面遗留的问题吗?答案是可以的。
在这里插入图片描述
在这里插入图片描述
那么这个smart_ptr还有一些什么问题呢?
在这里插入图片描述

没错就是拷贝构造或者拷贝赋值的时候就会出问题,因为析构的时候同一块空间会被析构两次,这时候就会报错。那么该怎么解决呢?

auto_ptr

这时候就有人提出了管理权转移的思想来解决这个问题。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
大家可以看到auto_ptr很好的解决了上面的问题,但是auto_ptr自身有一个很大的问题大家知道吗?就是悬空问题。
在这里插入图片描述
从上图可以看出p1变成悬空指针,且程序无法正常运行。
从中可以看出auto_ptr是一个失败的设计,并且很多公司都禁止使用auto_ptr.

unique_ptr

经过上面的尝试发现不行后,有人就想出了一个简单粗暴的办法,我直接防拷贝不就好了,也不用想那么多。
在这里插入图片描述
在这里插入图片描述

shared_ptr

但是要是我们真的需要多个指针,管理一块空间那该怎么解决之前的那个问题呢?这时候就用到了shared_ptr。
shared_ptr的思想是用引用计数来解决多个指针指向同一块空间的问题。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从上面我们可以看到,shared_ptr解决了之前的问题。那么上面实现的shared_ptr还有什么问题?线程安全问题。
在这里插入图片描述
在这里插入图片描述

我们可以看到,当n较小的时候并不会发生线程安全问题,但是当比较大的时候呢?
在这里插入图片描述
我们可以看到当n为10万的时候就发生了线程安全问题。
所以我们应该加锁。

线程安全的解决

在这里插入图片描述
在这里插入图片描述
我们可以看到加锁后,引用计数变的正常,智能指针也正常析构。这时大家肯就会有问题,为什么数据++的不正确?那么shared_ptr还是线程安全的吗?算。
在这里插入图片描述

循环引用

那么现在的shared_ptr就完整了吗?它还有没有什么问题?每次就是循环引用。
在这里插入图片描述
在这里插入图片描述
==我们可以看到最终对象没有被销毁。==那么没有循环引用呢?
在这里插入图片描述
==我们可以看到,没有循环引用时,对象被正常销毁。==那么该怎么解决这个问题呢?这时就用到了weak_ptr。

weak_ptr

weak_ptr的思想就是,只使用,不负责管理和释放。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

删除器

删除器需要我们自己写一个仿函数,显示传给智能指针
在这里插入图片描述

在这里插入图片描述
这里实现的是unique_ptr的删除器,shared_ptr的删除器底层实现比较麻烦大家有兴趣可以自己去了解。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值