0

0

C++怎么使用智能指针_C++内存管理教程【现代】

穿越時空

穿越時空

发布时间:2026-02-22 18:10:52

|

159人浏览过

|

来源于php中文网

原创

std::unique_ptr必须用std::make_unique初始化以避免内存泄漏;shared_ptr循环引用需用weak_ptr打破;禁止混用智能指针与裸指针进行双重管理或释放操作。

c++怎么使用智能指针_c++内存管理教程【现代】

std::unique_ptr 怎么初始化才不会崩溃

直接用裸指针初始化 std::unique_ptr 是最常见崩点。比如写 std::unique_ptr<int> p(new int(42))</int> 看似没问题,但一旦构造函数抛异常(比如 int 的构造里 throw),new 出来的内存就泄露了——因为 unique_ptr 构造还没完成,析构器根本没接管。

正确做法只有一条:用 std::make_unique

  • std::make_unique<int>(42)</int> —— 安全,分配和构造原子完成
  • 别手动 new + 传入构造函数,尤其别对数组用 std::unique_ptr<int>(new int[10])</int>,应改用 std::make_unique<int>(10)</int>
  • 如果必须从裸指针接手(比如 C API 返回的指针),用 std::unique_ptr<t>(raw_ptr)</t> 后立刻检查 raw_ptr != nullptr,否则空指针移交会调用 delete nullptr(虽标准允许,但某些自定义 deleter 会崩)

std::shared_ptr 循环引用怎么破

两个 std::shared_ptr 互相持有对方管理的对象,引用计数永远不降到 0,对象就永远不释放——典型场景是父子结构、观察者回调、lambda 捕获自身 shared_ptr

核心解法不是“少用 shared_ptr”,而是明确谁该强引用、谁该弱引用。

AI Home Tab
AI Home Tab

把你喜欢的AI放到首页

下载

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

  • 父持有子用 std::shared_ptr,子反向引用父必须用 std::weak_ptr
  • 在 lambda 里捕获 shared_ptr 自身?改成捕获 weak_ptr,调用前用 lock() 转成临时 shared_ptr,失败就说明对象已销毁
  • 别用 shared_from_this() 在构造函数里调用——此时控制块还没建好,行为未定义

智能指针和 raw pointer 混用时哪些操作绝对不能做

混用本身不违法,但几类操作一做就踩内存或 double-free。

  • std::unique_ptr.get() 返回的裸指针再传给另一个智能指针构造(比如又塞进 std::shared_ptr)——双重管理,必崩
  • get() 出来的指针调用 deletefree——智能指针还在管,释放后变成悬垂指针
  • std::shared_ptrget() 结果存成全局裸指针并长期使用——忘了它可能随时被释放,下次访问就是 UAF
  • std::shared_ptr 管理栈对象(比如 int x; std::shared_ptr<int>(&x)</int>)——析构时 delete 栈地址,UB

move 语义下 unique_ptr 和 shared_ptr 行为差异

看起来都是“转移所有权”,但底层动作完全不同,影响性能和线程安全。

  • std::unique_ptr move 是纯指针赋值+置空,零开销,无原子操作,线程间传递需自行同步
  • std::shared_ptr move 会把控制块里的引用计数从源减 1、目标加 1,但 move 本身不修改引用计数(只转移控制块指针),所以比 copy 快,但仍涉及一次指针复制和原对象置空
  • 别对 shared_ptr 频繁 move 来“优化性能”——除非你在 hot path 且 profile 确认控制块访问是瓶颈,否则收益极小,还增加理解成本
  • move 后原 unique_ptr 变成空,访问 get() 返回 nullptr;而 shared_ptr move 后也为空,但它的控制块可能还在被其他副本引用

智能指针不是银弹,真正难的从来不是语法,而是判断“谁该拥有所有权”“生命周期边界在哪”。很多 crash 其实发生在跨模块、跨线程、或和 C 风格 API 交互时——那里没有自动管理,只有你写的那行 reset()release() 是否恰到好处。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

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

810

2023.08.02

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

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

579

2024.08.29

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

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

274

2025.08.29

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

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

210

2025.08.29

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

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

274

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

105

2025.10.23

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

192

2025.11.08

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

1030

2026.02.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 10万人学习

C 教程
C 教程

共75课时 | 4.9万人学习

C++教程
C++教程

共115课时 | 18.9万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号