讲师中心 微信公众号
AI工具推荐 视频效率加速

C++中的std::make_shared是什么?(为什么比直接new更快更安全)

胖涛同学_6519

胖涛同学_6519

发布时间:2026-02-13 10:07:50

|

440人浏览过

|

来源于php中文网

原创

std::make_shared 更高效因一次分配控制块与对象内存,避免两次分配导致的缓存不友好、CPU预取失效及内存争用;但不支持自定义删除器、别名构造、私有构造(无友元)、数组类型及自定义分配器(需用allocate_shared)。

c++中的std::make_shared是什么?(为什么比直接new更快更安全)

std::make_shared 为什么比 new + std::shared_ptr 构造更高效

因为 std::make_shared 能把控制块(control block)和对象内存一次分配完成,而 new 配合 std::shared_ptr 构造器要分配两次:一次给对象,一次给控制块。

这不只是“少一次 malloc”的问题——两次分配会增加缓存不友好性、影响 CPU 预取,还可能在高并发下加剧内存分配器争用。

  • 典型开销对比:std::shared_ptr<t>(new T(args...))</t> → 2 次堆分配;std::make_shared<t>(args...)</t> → 1 次堆分配(内部按需对齐并布局控制块+对象)
  • 仅当 T 的构造函数抛异常时,std::make_shared 的单次分配优势才会失效(此时控制块和对象都未构造成功,仍安全)
  • 注意:如果 T 有自定义 operator new,std::make_shared 不会调用它——它走的是全局 ::operator new 或 std::allocator 分配路径

哪些情况不能用 std::make_shared 替代 new

不是所有 std::shared_ptr 创建场景都适用 std::make_shared,最常见的是需要自定义删除器或别名构造的场合。

  • 需要非默认删除器:比如用 std::shared_ptr<int>(new int(42), [](int* p){ free(p); })</int>,std::make_shared 不支持传入删除器
  • 需要别名构造(aliasing constructor):如 std::shared_ptr<t>(ptr, other_ptr)</t>,用于共享控制块但指向不同子对象,make_shared 无法实现
  • T 的构造函数是私有/显式 delete,且没有友元允许 make_shared 访问(C++17 起,make_shared 对私有构造的支持依赖于类是否将 std::make_shared 声明为友元)
  • 需要传递 std::weak_ptr 到构造函数中(极少见,但某些循环引用规避模式会这样用)

std::make_shared 在 C++11/14/17 中的行为差异

主要差异集中在参数转发和异常安全性上,而不是内存布局逻辑本身。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

立即学习“C++免费学习笔记(深入)”;

  • C++11:完美转发参数,但若构造函数抛异常,控制块已分配却未被管理,存在微小泄漏风险(实际编译器普遍优化掉了)
  • C++14 起:标准明确要求异常安全——分配失败或构造失败时,控制块必须被正确释放,无需担心泄漏
  • C++17:引入了 std::make_shared 对 std::array 和聚合类型的更好支持,但普通类无变化;同时禁止编译器对 make_shared 做“返回值优化”以外的额外优化(保证控制块与对象同分配)
  • 所有版本都不支持数组类型直接构造:std::make_shared<int>()</int> 是非法的,必须用 std::shared_ptr<int>(new int[10])</int>

容易被忽略的坑:自定义分配器 + make_shared 的兼容性

很多人以为加个 std::allocator_arg 就能用自定义分配器调 make_shared,但事实是:标准库至今(C++20)仍未提供带分配器的 make_shared 重载。

  • std::make_shared 内部始终使用 std::allocator<t></t> 或全局 ::operator new,无视你传进来的任何分配器实例
  • 如果你真需要分配器感知的 shared_ptr,只能手动做两步:auto alloc = MyAlloc<t>{}; auto ptr = std::allocate_shared<t>(alloc, args...)</t></t> —— 注意是 std::allocate_shared,不是 make_shared
  • std::allocate_shared 行为和 make_shared 几乎一致,只是把分配器传给了控制块和对象的联合分配过程
  • 别名构造、自定义删除器这些限制,allocate_shared 同样不支持

事情说清了就结束。

热门AI工具

更多
创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6959

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3345

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4348

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2965

2025.08.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6427

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2688

2023.08.10

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

3291

2023.11.13

drop和delete的区别
drop和delete的区别

drop和delete的区别:1、功能与用途;2、操作对象;3、可逆性;4、空间释放;5、执行速度与效率;6、与其他命令的交互;7、影响的持久性;8、语法和执行;9、触发器与约束;10、事务处理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1005

2023.12.29

Uvicorn 报错与问题解决教程
Uvicorn 报错与问题解决教程

本专题汇总了Uvicorn服务器常见问题与报错解决的教程合集,涵盖启动失败、端口占用、模块导入错误、事件循环冲突及热重载失效等典型故障的排查思路。同时整理了多进程与Worker配置、SSL/HTTPS证书报错、跨域与代理配置等实战解决方案,助你快速定位并解决Uvicorn运行中的各类问题。

0

2026.11.02

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn