std::make_shared通过一次内存分配同时创建对象和控制块,减少开销、提升缓存局部性;保证异常安全,避免参数求值顺序导致的内存泄漏;并支持类型推导,使代码更简洁安全,是创建shared_ptr的首选方法。

使用 std::make_shared 相比于直接使用 new 配合 std::shared_ptr 构造,主要优势体现在内存分配效率和代码安全性上。核心在于:它将控制块(control block)与实际对象的内存分配合并为一次操作,减少了动态内存分配的开销。
内存分配次数优化
std::shared_ptr 内部需要两个部分:
指向实际对象的指针 控制块:包含引用计数、弱引用计数等管理信息
当这样写时:
std::shared_ptr ptr(new MyClass);
会发生两次独立的内存分配:
立即学习“C++免费学习笔记(深入)”;
new MyClass 分配对象内存 shared_ptr 构造时再分配控制块内存
而使用:
auto ptr = std::make_shared();
则只进行一次内存分配。这块内存同时包含:
MyClass 对象的存储空间 内联的控制块
这种合并分配减少了 heap 分配调用次数,降低内存碎片,提升缓存局部性,尤其在高频创建场景下性能更优。
异常安全保证
考虑函数调用:
foo(std::shared_ptr(new MyClass), bar());
虽然 new 和 shared_ptr 构造看似原子,但参数求值顺序未定义。可能执行顺序为:
执行 new MyClass(内存已分配) 调用 bar()(可能抛出异常) shared_ptr 构造未执行,导致内存泄漏
使用 make_shared 可避免此问题:
foo(std::make_shared(), bar());
因为 make_shared 调用本身是单个表达式,要么成功返回 shared_ptr,要么抛出异常但不会造成资源泄漏。
类型推导与代码简洁性
make_shared 利用模板参数推导,避免重复书写类型名:
auto ptr = std::make_shared(arg1, arg2);
相比:
std::shared_ptr ptr = std::shared_ptr(new MyClass(arg1, arg2));
更简洁,减少出错可能,也便于重构。
基本上就这些。make_shared 在性能、安全、可读性上都优于手动 new 配合 shared_ptr,应作为首选方式,除非需要自定义删除器或无法满足继承场景的多态构造需求。
以上就是C++ make_shared优势 内存分配优化分析的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1472195.html
微信扫一扫
支付宝扫一扫