当前位置:网站首页>探究make_shared效率
探究make_shared效率
2022-07-30 05:45:00 【尹平华】
Why Make_shared ?
C++11 中引入了智能指针, 同时还有一个模板函数 std::make_shared 可以返回一个指定类型的 std::shared_ptr, 那与 std::shared_ptr 的构造函数相比它能给我们带来什么好处呢 ?
优点
效率更高
shared_ptr 需要维护引用计数的信息,
- 强引用, 用来记录当前有多少个存活的 shared_ptrs 正持有该对象. 共享的对象会在最后一个强引用离开的时候销毁( 也可能释放).
- 弱引用, 用来记录当前有多少个正在观察该对象的 weak_ptrs. 当最后一个弱引用离开的时候, 共享的内部信息控制块会被销毁和释放 (共享的对象也会被释放, 如果还没有释放的话).
如果你通过使用原始的 new 表达式分配对象, 然后传递给 shared_ptr (也就是使用 shared_ptr 的构造函数) 的话, shared_ptr 的实现没有办法选择, 而只能单独的分配控制块:
1 2 | |

如果选择使用 make_shared 的话, 情况就会变成下面这样:
1 | |

内存分配的动作, 可以一次性完成. 这减少了内存分配的次数, 而内存分配是代价很高的操作.
关于两种方式的性能测试可以看这里 Experimenting with C++ std::make_shared
异常安全
看看下面的代码:
1 2 3 4 | |
C++ 是不保证参数求值顺序, 以及内部表达式的求值顺序的, 所以可能的执行顺序如下:
- new Lhs(“foo”))
- new Rhs(“bar”))
- std::shared_ptr
- std::shared_ptr
好了, 现在我们假设在第 2 步的时候, 抛出了一个异常 (比如 out of memory, 总之, Rhs 的构造函数异常了), 那么第一步申请的 Lhs 对象内存泄露了. 这个问题的核心在于, shared_ptr 没有立即获得裸指针.
我们可以用如下方式来修复这个问题.
1 2 3 | |
当然, 推荐的做法是使用 std::make_shared 来代替:
1 | |
缺点
构造函数是保护或私有时,无法使用 make_shared
make_shared 虽好, 但也存在一些问题, 比如, 当我想要创建的对象没有公有的构造函数时, make_shared 就无法使用了, 当然我们可以使用一些小技巧来解决这个问题, 比如这里 How do I call ::std::make_shared on a class with only protected or private constructors?
对象的内存可能无法及时回收
make_shared 只分配一次内存, 这看起来很好. 减少了内存分配的开销. 问题来了, weak_ptr 会保持控制块(强引用, 以及弱引用的信息)的生命周期, 而因此连带着保持了对象分配的内存, 只有最后一个 weak_ptr 离开作用域时, 内存才会被释放. 原本强引用减为 0 时就可以释放的内存, 现在变为了强引用, 若引用都减为 0 时才能释放, 意外的延迟了内存释放的时间. 这对于内存要求高的场景来说, 是一个需要注意的问题. 关于这个问题可以看这里 make_shared, almost a silver bullet
参考
边栏推荐
猜你喜欢

基于全球模式比较计划CMIP6与区域气候-化学耦合模式 WRF-Chem 的未来大气污染变化模拟

AAcell五号文档室——跨平台文件传输的小室一间一间的

R language application in the field of ecological environment

遥感、GIS和GPS技术在水文、气象、灾害、生态、环境及卫生等应用

十三、Kotlin进阶学习:内联函数let、also、with、run、apply的用法。

TDengine cluster construction

CLUE模型构建方法、模型验证及土地利用变化情景预测

点云统计滤波理解

七、Kotlin基础学习:1、创建类;2、构造函数;3、继承;4、封装;5、抽象类;6、接口;7、嵌套类;8、内部类;9、枚举类

Application of remote sensing, GIS and GPS technology in hydrology, meteorology, disaster, ecology, environment and health
随机推荐
基于遥感解译与GIS技术环境影响评价图件制作(最新导则)
R语言 生态环境领域应用
Jdbc & Mysql timeout分析
Map making of environmental impact assessment based on remote sensing interpretation and GIS technology (the latest guidelines)
使用kotlin扩展插件/依赖项简化代码(在最新版本4.0以后,此插件已被弃用,故请选择性学习,以了解为主。)
基于R语言地理加权回归、主成分分析、判别分析等空间异质性数据分析
MySQL index optimization and failure scenarios
无人机生态环境监测、图像处理与GIS数据分析
Dropout原理及作用
[Getting C language from zero basis - navigation summary]
SQL Server Installation Tutorial
Rsync实现Win系统间的文件夹或数据同步
Self-augmented Unpaired Image Dehazing via Density and Depth Decomposition program running record
QT连载1:readyRead()函数,数据分包不完整解决办法
R language application in the field of ecological environment
八、Kotlin基础学习:1、数据类;2、单例;3、伴生对象;4、密封类;
DeepLearing4j's deep learning Yolo Tiny realizes target detection
nodejs PM2监控及报警邮件发送(二)
MySQL 特殊语句及优化器
迪文串口屏幕制作(连载一)=====准备工作