struct A;
std::shared_ptr<A> p1 = std::make_shared<A>();
std::shared_ptr<A> p2(new A);

上面两者有什么区别呢? 区别是:std::shared_ptr构造函数会执行两次内存申请,而std::make_shared则执行一次。

std::shared_ptr在实现的时候使用的refcount技术,因此内部会有一个计数器(控制块,用来管理数据)和一个指针,指向数据。因此在执行std::shared_ptr<A> p2(new A)的时候,首先会申请数据的内存,然后申请内控制块,因此是两次内存申请,而std::make_shared<A>()则是只执行一次内存申请,将数据和控制块的申请放到一起。那这一次和两次的区别会带来什么不同的效果呢?

异常安全

考虑下面一段代码:

void f(std::shared_ptr<Lhs> &lhs, std::shared_ptr<Rhs> &rhs){...}f(std::shared_ptr<Lhs>(new Lhs()),std::shared_ptr<Rhs>(new Rhs())
);

因为C++允许参数在计算的时候打乱顺序,因此一个可能的顺序如下:

  1. new Lhs()
  2. new Rhs()
  3. std::shared_ptr
  4. std::shared_ptr

此时假设第2步出现异常,则在第一步申请的内存将没处释放了,上面产生内存泄露的本质是当申请数据指针后,没有马上传给std::shared_ptr,因此一个可能的解决办法

auto lhs = std::shared_ptr<Lhs>(new Lhs());
auto rhs = std::shared_ptr<Rhs>(new Rhs());
f(lhs, rhs);

而一个比较好的方法是使用std::make_shared

f(std::make_shared<Lhs>(),std::make_shared<Rhs>()
);

make_shared的缺点

因为make_shared只申请一次内存,因此控制块和数据块在一起,只有当控制块中不再使用时,内存才会释放,但是weak_ptr却使得控制块一直在使用。

make_shared和shared_ptr的区别相关推荐

  1. make_shared

    make_shared函数的主要功能是在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr;由于是通过shared_ptr管理内存,因此一种安全分配和使用动态内存的方法. 如下为m ...

  2. C++ make_shared() shared_ptr()用法(七)

    1.make_shared.shared_ptr用法   shared_ptr很好地消除了显式的delete调用,如果读者掌握了它的用法,可以肯定delete将会在你的编程字典中彻底消失 .但这还不够 ...

  3. c++11 shared_ptr 与 make_shared源码剖析

    写在最前... 请支持原创~~ 0. 前言 所谓智能指针,可以从字面上理解为"智能"的指针.具体来讲,智能指针和普通指针的用法是相似的,不同之处在于,智能指针可以在适当时机自动释放 ...

  4. shared_ptr 和 make_shared 的使用(以及qt信号和槽连接)

    std::shared_ptr 是一种智能指针(本身就是一个对象,一个对象,一个对象,不是原始指针,重要的事情说三遍),指向一个对象.它能够记录多少个 shared_ptr 共同指向一个对象,从而消除 ...

  5. (六)boost库之内存管理shared_ptr

    1.shared_ptr的基本用法 boost::shared_ptr<int> sp(new int(10)); //一个指向整数的shared_ptr assert(sp.unique ...

  6. 智能指针shared_ptr、unique_ptr、weak_ptr

    智能指针 智能指针解决的问题 智能指针分类 shared_ptr 内存模型图 shared_ptr示例 shared_ptr含义 shared_ptr基本用法及常用函数 常用函数 智能指针的构造,初始 ...

  7. C++智能指针shared_ptr、unique_ptr以及weak_ptr

    目录 shared_ptr类 shared_ptr和unique_ptr都支持的操作 shared_ptr独有的操作 make_shared函数 shared_ptr自动销毁所管理的对象 由普通指针管 ...

  8. 智能指针(shared_ptr、unique_ptr、weak_ptr)的使用

    智能指针的使用 一.shared_ptr 1.创建一个shared_ptr 2.shared_ptr的常用成员函数 reset成员函数的使用 3.==注意事项== 二.unique_ptr 1.uni ...

  9. shared_ptr的坑

    new与赋值的坑 赋值(assignment)和new运算符在C++与Java(或C#)中的行为有本质的区别.在Java中,new是对象的构造,而赋值运算是引用的传递:而在C++中,赋值运算符意味着& ...

最新文章

  1. linux c 获取 CPU、内存、IO、磁盘、网速
  2. mseloss 与 smooth_l1_loss比较
  3. C# 方法中的this参数
  4. datagridview选中获取行号_DataGridView控件显示行号的正确代码及分析
  5. OllyDbg笔记-软件逆向调试技巧
  6. 重试次数配置_Stelnet(ssh)登陆华为交换机配置教程
  7. js 单精度浮点数转10进制_js浮点数精度问题的前世今生?
  8. CMYK、RGB颜色对照表
  9. 2018年深圳杯论文_2018年深圳杯数学建模挑战赛通知及题目
  10. 软件测试工作中有哪些常用的工具?
  11. hbuilder TODO插件
  12. Android 文件存储-图片存储
  13. aws认证,aws有哪些认证,有什么用
  14. android 无法添加帐户,android - Android SecurityException:uid xxxxx无法显式添加帐户 - 堆栈内存溢出...
  15. APEX是NVIDIA PhysX技术的一个强有力的补充
  16. 声源定位MATLAB的程序,求大神改一个声源定位程序 改成放置录音文件然后定位...
  17. python linux上屏幕截图_在Linux上通过Python脚本拍摄屏幕截图
  18. WPS智能填充数据的方法
  19. 使用python将图片格式转换为ico格式
  20. 对Polyspace的几点思考

热门文章

  1. 成功解决tensorflow.keras: AttributeError: ‘str‘ object has no attribute ‘decode‘
  2. redis强一致性_分布式架构一定要有Redis吗?Redis的常见问题我都帮你解答了
  3. qtdesigner设计表格_实例9 利用Qt Designer设计一个对话框
  4. JAVA_HOME系统环境变量
  5. odciexttableopen 调用出错 error open log_如何在 Spring 异步调用中传递上下文
  6. 浏览器打开出现证书错误_浏览器安全证书过期怎么办
  7. 牛客练习赛26B 烟花 (概率DP)
  8. 记一次Linux服务器因redis漏洞的挖矿病毒入侵
  9. Linux文件系统与日志
  10. nodejs+vue.js+webpack