相信不少同学都在面试中都被问到过c++智能指针的问题,接踵而至的必定是循环引用了,而我每次的答案都是一招鲜:因为它们都在互相等待对方先释放,所以造成内存泄漏。面试官很满意,我也很满意。

但是为啥要等到对方先释放?在我内心也曾有个问号。。

智能指针起源

所谓人类进步的阶梯就是懒,曾几何时,就有人想,我把new 运算符返回的指针p交给一个对象“托管”,而不用操心在哪里去释放这个指针p,由这个托管者自动的在合适的时机进行指针p的释放,这样也不怕自己忘记释放指针p了。而且,我这边操作托管者,要跟操作原来的指针一毛一样,这样才方便。即假设托管指针p的对象叫做shared_ptr,那么

*shared_ptr 所指,便是 *p 所向!

第一章 auto_ptr

最早的智能指针类,实现了*运算符。你用它实例化出来一个类对象,用起来就好像指针一样。对象的特性自然是在作用域结束时,自动调用析构函数实现自我销毁。如此一来,攻城狮们便可不再操心何时释放指针,而可以随心所欲的摸鱼啦。

但其有个致命缺陷:因为其缺省的复制和赋值构造函数,带来的同一个对象被多个智能指针托管,释放的时候便混乱异常,一不小心就重复释放了,使得用户使用起来战战兢兢,老早就被淘汰了。

第二章 unique_ptr

为了规避auto_ptr可以随意复制和赋值构造的缺陷,就推出了unique_ptr, 其实就是给auto_ptr简单换了个名字,并禁用掉其默认的复制和赋值构造函数,好嘛,大家都别用了<(`^′)>,不写代码,就不会有bug!

第三章 shared_ptr

只有一个unique_ptr,对于省吃俭用的高级攻城狮们来说自然是不够的,于是就有人站了出来喊了一声:我们要搞共享经济——砰!基于引用计数的shared_ptr横空出世了,每多一个人持有这个对象,引用计数就加一;每少一个人持有这个对象,引用计数就减一。引用计数为零时,才做真正的销毁操作。

很快,梦魇悄然而至,“我的shared_ptr怎么没有释放?”——一位焦头烂额的格子少年路过。。

起初,没有人在意这场灾难,这不过是一个指针的丢失、一个bug,一个服务器的宕机,直到这场灾难和每个人息息相关......

"你看这个人写的代码,它好像一坨狗屎"

#include <iostream>class B;
class A {
public:A() {std::cout << "A" << std::endl;}~A() {std::cout << "~A" << std::endl;}
public:std::shared_ptr<B> ptr;
};class B {
public:B() {std::cout << "B" << std::endl;}~B() {std::cout << "~B" << std::endl;}
public:std::shared_ptr<A> ptr;
};void fun() {std::shared_ptr<A> pa(new A());std::shared_ptr<B> pb(new B());pa->ptr = pb;pb->ptr = pa;
}int main()
{fun();return 0;
}

运行结果我不敢看: (*/ω\*)

纳尼?A和B的析构函数都没有被调用,妥妥的内存泄漏了!

事后,据某位亲身经历这次事件的大牛回忆说:“喔,当时的内存布局是这个样子的!”

“对象A同时被pa和对象B中的ptr两个智能指针托管,所以引用计数为2;对象B同时被pb和对象
A中的ptr两个智能指针托管,所以引用计数也为2。那么当fun函数执行完,栈对象pb、pa依次开始执行这样的析构函数:”

// 大牛随手写的析构函数伪代码
// Copyright 2022 DaNiu. All rights reserved.if (--ref_cnt == 0) delete obj;

“紧接着内存布局就变成了这样:”

“pa和pb已经销毁了,然而对象A和B,已经迷失在这浩瀚内存中,亘古难灭。。。吾称之为循环引用!”

路人震惊:“嘶!随着这样的迷失越来越多,这片天地再也无人可搞对象!!!”

゜゜(´O`) ゜゜。:“不要啊!我还没有搞过对象呢。”

......

庆幸的是,不就之后,有人就在shared_ptr出世的那方世界的一个不起眼的角落里,发现了一个小家伙,伴shared_ptr而生。

终章 weak_ptr

为了解决shared_ptr在在循环引用中存在的资源泄漏问题,weak_ptr在这种场景下应用而生,weak_ptr指向的智能指针对象,其引用计数不会加一,也就不会存在无法释放的问题了。

解决的方法就是,把A和B其中的一个ptr改成weak_ptr。

智能指针循环引用——你真的懂了吗?相关推荐

  1. 智能指针循环引用问题

    智能指针循环引用 循环引用简单来说就是:两个对象互相使用一个shared_ptr成员变量指向对方,这会造成循环引用.导致引用计数失效,内存无法释放. #include <iostream> ...

  2. [zz] C++智能指针循环引用解决

    转载自:http://blog.csdn.net/segen_jaa/article/details/8080167 参考文章:http://www.cnblogs.com/TianFang/arch ...

  3. VTK修炼之道80:VTK开发基础_智能指针与引用计数

    1.引用计数 VTK经过多年的开发与维护,已经形成了一套稳定的框架和开发规则.因此,了解这些规则和框架是定制VTK类的基础,这其中用到了大量面向对象的设计模式,例如对象工程模式.观察者/命令模式:还有 ...

  4. c++智能指针与引用计数

    一. 引用计数 先写一个简单的学生类 #include<iostream> #include <string.h> using namespace std;class stud ...

  5. C++(9)--裸指针、智能指针、引用

    指针 1.裸指针的基本概念 1.1 裸指针的声明*/初始化& 1.2 操作裸指针--间接运算符* 1.3 裸指针使用 demo--指向一个简单变量 1.4 空指针--nullptr 1.5 特 ...

  6. 智能指针shared_ptr引用计数工作原理

    引用计数原理 shared_ptr的实现是这样的:  shared_ptr模板类有一个__shared_count类型的成员_M_refcount来处理引用计数的问题.__shared_count也是 ...

  7. 指针与数组——你真的懂么?

    文章目录 本文目的 地址类型 与 指针变量 什么是数组 数组的数组 多维数组的区别 a[0] []运算符本质 指向数组的指针 int (*p)[9]; 字符串常量 c语言声明 复杂指针解析:右左法则 ...

  8. C++总结8——shared_ptr和weak_ptr智能指针

    http://blog.csdn.net/wendy_keeping/article/details/75268687 智能指针的提出:智能指针是存储指向动态分配对象指针的类,用于生存期控制.能够确保 ...

  9. C++ — 智能指针的简单实现以及循环引用问题

    http://blog.csdn.net/dawn_sf/article/details/70168930 智能指针 _________________________________________ ...

最新文章

  1. docker 容器中的 uid 和 gid
  2. 《How Tomcat Works》读书笔记(二)
  3. Oracle 11g Release 2 (11.2) for Microsoft Windows (32-Bit)安装与卸除
  4. Knative 实战:三步走!基于 Knative Serverless 技术实现一个短网址服务
  5. Training的第十六天
  6. 密码学 区块链中的应用专栏 【简介】
  7. ajax兼容低版本浏览器
  8. 不同文件格式打开的方法
  9. 重发布直连路由到 OSPF
  10. Linux好用命令之base64命令
  11. 国外创业者分享之Android 与 iOS:猜猜哪个能让开发者赚得更多
  12. 基础操作案例:ArcGIS PRO基础教程(二)
  13. 易经的奥秘》笔记--台湾师范大学曾仕强
  14. 当年明月、袁腾飞、阎崇年三人的专业水平的比较以及由此想到的一些学习方法、品书原则
  15. 百度地图实现公司位置的定位,可拖动修改公司位置。
  16. 点阵屏HCMS-3977驱动
  17. php 屏蔽浸膏,【佳学基因】副甲状腺浸膏基因检测
  18. matlab 调用摄像头拍照
  19. 终年57岁!中国科学院院士因病逝世
  20. 人工神经网络教程第四版,人工神经网络教程视频

热门文章

  1. 浅谈面试中常提到的乐观锁与悲观锁
  2. 高通Camx offline Log merge命令
  3. Parallel HDF5 简介
  4. RMON MIB:远程监控管理信息库
  5. 系统动力学专拓考试重点总结
  6. BM46 最小的K个数
  7. 步进电机主要技术参数
  8. 空调弱周期到了!海尔发力空气网,线上线下唯一双增长
  9. 这是我见过最好的Python教程:十分钟带你认识Python
  10. 让家长实时了解孩子进出校园——智能校园管理系统