本文基于C++标准库源码分析shared_ptr,旨在搞清楚shared_ptr是什么,线程安全性等,目标能够安全的使用智能指针。

(一)shared_ptr是一个类。

首先可以确定的是shared_ptr是一个类,那么就可以通过类的内存空间来从本质上分析它的结构。

通过sizeof()一个shared_ptr可以观察到它的大小为8个字节,然后追踪源代码发现它继承一个__shared_ptr类,这个类包含了两个组件:一个指针和一个类。

_M_ptr很好理解,就是一个指向你所保护的对象的指针(4字节)。

那么重点观察__shared_count<_Lp>是个什么东西。我们继续追踪源代码,可以看到__shared_count包含一个_Sp_counted_base类型的指针(4字节)

而这个_Sp_coutned_base类又有什么呢? 两个int类型的记数变量。

一个记录引用计数,一个记录weak_ptr的数量。现在通过层层剖析,我们可以画出shared_ptr的内存空间,如图所示:

而shared_ptr的构造函数也就是主要构造这两个东西,我们把重点放在计数类的构造上,看看它是如何实现线程安全的引用计数的。

首先_Sp_count_base模板类型_Lp是一个枚举,分别是_S_single、_S_mutex、_S_atomic。分别对应不同的计数方法,我们重点来看原子操作:

非常经典的CAS操作,__count为当前引用数,如果当前引用计数为0则抛出异常。利用do-while实现安全的操作。while里的函数原型为:

bool__atomic_compare_exchange_n (type *ptr, type *expected, type desired,boolweak,intsuccess_memorder,intfailure_memorder);

expected就是旧值,desired就是我们要+1后得到的新值,如注释所说,与旧值对比如果没变化则+1,否则就会返回false不断循环。

本篇主要讲解shared_ptr这个类的本质,简单介绍了它的两个组件,以及计数类是如何用原子操作实现线程安全的计数,下篇我们讲解shared_ptr的线程安全性,探讨多线程下对shared_ptr的读写安全问题。

深入理解智能指针之shared_ptr(一)的更多相关文章

  1. C++ | 再探智能指针(shared_ptr 与 weak_ptr)

    上篇博客我们模拟实现了 auto_ptr 智能指针,可我们说 auto_ptr 是一种有缺陷的智能指针,并且在C++11中就已经被摈弃掉了.那么本章我们就来探索 boost库和C++11中的智能指针以 ...

  2. 智能指针之shared_ptr基本概述

    1.shared_ptr允许有多个指针指向同一个对象,unique_ptr独占所指向的对象. 2.类似于vector,智能指针也是模板.创建智能指针: shared_ptr<string> ...

  3. 【C++11新特性】 C++11智能指针之shared_ptr

    C++中的智能指针首先出现在“准”标准库boost中.随着使用的人越来越多,为了让开发人员更方便.更安全的使用动态内存,C++11也引入了智能指针来管理动态对象.在新标准中,主要提供了shared_p ...

  4. C++智能指针之shared_ptr与右值引用(详细)

    1. 介绍 在 C++ 中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露.解决这个问题最有效的方法是使用智能指针(smart pointer).智能指针是存储指向动态分配(堆)对象指针 ...

  5. 【STL学习】智能指针之shared_ptr

    前面已经学习过auto_ptr,这里补充另外一种智能指针,比auto_ptr要更强力更通用的shared_ptr. shared_ptr 简介及使用选择  几乎所有的程序都需要某种形式的引用计数智能指 ...

  6. C++智能指针: auto_ptr, shared_ptr, unique_ptr, weak_ptr

    本文参考C++智能指针简单剖析 内存泄露 我们知道一个对象(变量)的生命周期结束的时候, 会自动释放掉其占用的内存(例如局部变量在包含它的第一个括号结束的时候自动释放掉内存) int main () ...

  7. [5] 智能指针boost::shared_ptr

    [1]boost::shared_ptr简介 boost::shared_ptr属于boost库,定义在namespace boost中,包含头文件#include<boost/shared_p ...

  8. 关于智能指针boost::shared_ptr

    boost库中的智能指针shared_ptr, 功能强大, 且开销小,故受到广大coder的欢迎. 但在实际的使用过程中,笔者也发现了一些不足. 1.定制的删除器 shared_ptr除了可以使用默认 ...

  9. 智能指针(二):shared_ptr实现原理

    前面讲到auto_ptr有个很大的缺陷就是所有权的转移,就是一个对象的内存块只能被一个智能指针对象所拥有.但我们有些时候希望共用那个内存块.于是C++ 11标准中有了shared_ptr这样的智能指针 ...

随机推荐

  1. tableZen maxHeight 解决方案 如果数据条数小于N,不进行高度设置,超过N条,直接设置高度,解决原生iview Table 对于右侧固定列,不能计算出正确数值的解决方案

    tableZen maxHeight 解决方案 如果数据条数小于N,不进行高度设置,超过N条,直接设置高度,解决原生iview Table 对于右侧固定列,不能计算出正确数值的解决方案 if (thi ...

  2. 在d盘创建文件夹,里面有aaa.txt/bbb.txt/ccc.txt,然后遍历出aaa文件夹下的文件(新手)

    //导入的包.import java.io.File;import java.io.IOException;//创建的一个类.public class zy { //公共静态的主方法. public ...

  3. eclipse、 IDEA中字母大小写转换快捷键

    eclipse 中字母大小写切换快捷键: ctrl + shift + x     转为大写 ctrl + shift + y     转为小写 IDEA  中字母大小写切换快捷键: ctr + sh ...

  4. DRF之restful规范、Postman接口测试

    一. DRF简介 Django REST框架是一个功能强大且灵活的工具包,用于构建Web API. 使用REST框架的一些原因: 该网站可浏览API是你的开发人员一个巨大的可用性胜利. 身份验证策略包 ...

  5. centos 安装activeMq

    Apache ActiveMQ是一个免费的开源消息代理和集成模式服务器.它支持来自JAVA.c++.C.Python.Perl.PHP等多种语言的客户端和协议.它提供了许多功能,如消息组.虚拟目的地. ...

  6. centos7 LVM扩容案例

    测试数据 cd / && dd if=/dev/zero of=file bs=1M count=10000 将磁盘变大的测试命令. 生产环境不要用. 这只是用于测试扩容后的效果 LV ...

  7. uni-app实现文件上传(h5方式)

    1.嵌入H5页面,需要采用web-view标签,如下: <web-view src="/hybrid/html/index.html" @message="hand ...

  8. Java 添加、删除Excel表单控件

    通过表单控件,用户可以快速地将数据填写到模板文档中,轻松引用单元格数据并与其进行交互.本文通过Java代码示例介绍如何在Excel表格中添加表单控件,包括文本框.单选按钮.复选框.组合框.微调按钮等: ...

  9. BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树

    题意 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量. 他们每天都生活在巨大的压力之下.小强建立了一个模型.这世界上有N个网络设备, ...

  10. 「MoreThanJava」当大学选择了计算机之后应该知道的

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...