C++——智能指针 weak_ptr

weak_ptr这个指针天生一副小弟的模样,也是在C++11的时候引入的标准库,它的出现完全是为了弥补它老大shared_ptr天生有缺陷的问题。只能配合shared_ptr一起使用

shared_ptr 循环引用 造成的后果:存在资源泄露

一、shared_ptr 的循环引用

什么是循环引用的问题呢?在shared_ptr的使用过程中,当强引用计数为0时,就会释放所指向的堆内存。那么问题来了,如果和死锁一样,当两个shared_ptr互相引用,那么它们就永远无法被释放了。

cpp 复制代码
struct ListNode
{
    int _data;
    shared_ptr<ListNode> _prev;
    shared_ptr<ListNode> _next;
    ~ListNode() { cout << "~ListNode()" << endl; }
};
int main()
{
    shared_ptr<ListNode> node1(new ListNode);
    shared_ptr<ListNode> node2(new ListNode);

    node1->_next = node2;
    node2->_prev = node1;

    return 0;
}

以上代码运行,检测到如下内存泄露:

分析:定义出来的sp1和sp2都有如下的结构, 首先sp1是一个智能指针shared_ptr,所以它有它的_ptr和_pCount字段,其次ListNode结构的结点内部有三个成员变量,分别为data next prev,而且这个next和prev它俩也是俩个shared_ptr智能指针对象,也有其自己的_ptr和_pCount,于是定义出来的sp1对象就有如下的结构。sp2结构也和此图一致。

经过如下的链接操作后:形成如下图的链接结构。

cpp 复制代码
    node1->_next = node2;
    node2->_prev = node1;

随后,程序执行结束,进入到对象的析构环节,后创建的元素先析构,先进行sp2对象的析构,根据shared_ptr计数功能,对右边计数器进行--操作,发现计数器无法归零,所以不能对sp2资源进行释放,转而进行sp1对象的析构处理,但是对左侧计数器进行--操作后,发现仍然不能归零,俩个对象中的next和prev分别造成了不同计数器的无法归零,就导致内存泄露,资源无法回收。

二、weak_ptr 解决循环引用

标准库提供了weak_ptr,唯一作用就是帮助shared_ptr解决循环引用的问题

weak_ptr不能管理资源,只能配合shared_ptr一起使用。

如此修改之后,俩个对象正常进行析构,并且没有产生资源泄露。

三、为什么weak_ptr能解决这个问题?

未完待续

相关推荐
j7~2 分钟前
【C++】STL--string类--拆析解剖string类的实现以及string类的底层详解(2)
开发语言·c++·浅拷贝·深拷贝·string类的实现·string拷贝构造·string赋值重载
程序员二叉11 分钟前
【JUC】AQS底层深度拆解|独占/共享模式|队列原理全详解
java·开发语言·面试·juc
踏着七彩祥云的小丑13 分钟前
Go 学习第6天:结构体 + 切片 + range遍历
开发语言·学习·golang·go
读书札记202216 分钟前
Qt中windeployqt.exe工具的使用:解决使用CMake创建的项目点击exe文件后系统提示0xc000007b的问题
开发语言·qt
xiaoshuaishuai828 分钟前
C# 定制化Markdown编辑器
开发语言·c#·编辑器
DogDaoDao28 分钟前
C++核心技术深度剖析:从底层原理到工程实践
开发语言·c++·面试·程序员·指针·虚函数
磊 子32 分钟前
C++移动语义和智能指针
java·开发语言·c++
不负岁月无痕35 分钟前
C++继承与多态知识点及其高频面试问题
开发语言·c++·面试
June`38 分钟前
如何组织一个并行程序
开发语言·cuda
dtq04241 小时前
C语言刷题函数1-判断素数(分支语句,函数两种方法)
c语言·开发语言·学习