make_shared和shared_ptr的区别
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++允许参数在计算的时候打乱顺序,因此一个可能的顺序如下:
- new Lhs()
- new Rhs()
- std::shared_ptr
- 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的区别相关推荐
- make_shared
make_shared函数的主要功能是在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr;由于是通过shared_ptr管理内存,因此一种安全分配和使用动态内存的方法. 如下为m ...
- C++ make_shared() shared_ptr()用法(七)
1.make_shared.shared_ptr用法 shared_ptr很好地消除了显式的delete调用,如果读者掌握了它的用法,可以肯定delete将会在你的编程字典中彻底消失 .但这还不够 ...
- c++11 shared_ptr 与 make_shared源码剖析
写在最前... 请支持原创~~ 0. 前言 所谓智能指针,可以从字面上理解为"智能"的指针.具体来讲,智能指针和普通指针的用法是相似的,不同之处在于,智能指针可以在适当时机自动释放 ...
- shared_ptr 和 make_shared 的使用(以及qt信号和槽连接)
std::shared_ptr 是一种智能指针(本身就是一个对象,一个对象,一个对象,不是原始指针,重要的事情说三遍),指向一个对象.它能够记录多少个 shared_ptr 共同指向一个对象,从而消除 ...
- (六)boost库之内存管理shared_ptr
1.shared_ptr的基本用法 boost::shared_ptr<int> sp(new int(10)); //一个指向整数的shared_ptr assert(sp.unique ...
- 智能指针shared_ptr、unique_ptr、weak_ptr
智能指针 智能指针解决的问题 智能指针分类 shared_ptr 内存模型图 shared_ptr示例 shared_ptr含义 shared_ptr基本用法及常用函数 常用函数 智能指针的构造,初始 ...
- C++智能指针shared_ptr、unique_ptr以及weak_ptr
目录 shared_ptr类 shared_ptr和unique_ptr都支持的操作 shared_ptr独有的操作 make_shared函数 shared_ptr自动销毁所管理的对象 由普通指针管 ...
- 智能指针(shared_ptr、unique_ptr、weak_ptr)的使用
智能指针的使用 一.shared_ptr 1.创建一个shared_ptr 2.shared_ptr的常用成员函数 reset成员函数的使用 3.==注意事项== 二.unique_ptr 1.uni ...
- shared_ptr的坑
new与赋值的坑 赋值(assignment)和new运算符在C++与Java(或C#)中的行为有本质的区别.在Java中,new是对象的构造,而赋值运算是引用的传递:而在C++中,赋值运算符意味着& ...
最新文章
- linux c 获取 CPU、内存、IO、磁盘、网速
- mseloss 与 smooth_l1_loss比较
- C# 方法中的this参数
- datagridview选中获取行号_DataGridView控件显示行号的正确代码及分析
- OllyDbg笔记-软件逆向调试技巧
- 重试次数配置_Stelnet(ssh)登陆华为交换机配置教程
- js 单精度浮点数转10进制_js浮点数精度问题的前世今生?
- CMYK、RGB颜色对照表
- 2018年深圳杯论文_2018年深圳杯数学建模挑战赛通知及题目
- 软件测试工作中有哪些常用的工具?
- hbuilder TODO插件
- Android 文件存储-图片存储
- aws认证,aws有哪些认证,有什么用
- android 无法添加帐户,android - Android SecurityException:uid xxxxx无法显式添加帐户 - 堆栈内存溢出...
- APEX是NVIDIA PhysX技术的一个强有力的补充
- 声源定位MATLAB的程序,求大神改一个声源定位程序 改成放置录音文件然后定位...
- python linux上屏幕截图_在Linux上通过Python脚本拍摄屏幕截图
- WPS智能填充数据的方法
- 使用python将图片格式转换为ico格式
- 对Polyspace的几点思考
热门文章
- 成功解决tensorflow.keras: AttributeError: ‘str‘ object has no attribute ‘decode‘
- redis强一致性_分布式架构一定要有Redis吗?Redis的常见问题我都帮你解答了
- qtdesigner设计表格_实例9 利用Qt Designer设计一个对话框
- JAVA_HOME系统环境变量
- odciexttableopen 调用出错 error open log_如何在 Spring 异步调用中传递上下文
- 浏览器打开出现证书错误_浏览器安全证书过期怎么办
- 牛客练习赛26B	烟花 (概率DP)
- 记一次Linux服务器因redis漏洞的挖矿病毒入侵
- Linux文件系统与日志
- nodejs+vue.js+webpack