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

C++中智能指针能管理数组吗?探讨unique_ptr数组特化

落涛酱_7021

落涛酱_7021

发布时间:2025-06-28 08:10:02

|

1051人浏览过

|

来源于php中文网

原创

c++中智能指针可以管理数组,但需注意不同指针的使用方式。1. unique_ptr支持数组特化,使用unique_ptr可自动调用delete[]释放内存,是管理动态数组的首选;2. shared_ptr默认析构调用delete而非delete[],需提供自定义删除器方可安全管理数组;3. 使用shared_ptr管理数组时不能直接用operator[]访问元素,必须通过get()获取原始指针;4. 风险包括忘记设置删除器、降低代码可读性及性能开销;5. 可通过编写工厂函数统一创建shared_ptr或考虑使用std::vector避免错误。

C++中智能指针能管理数组吗?探讨unique_ptr数组特化

C++中,智能指针是可以管理数组的,但需要特别注意。unique_ptr可以通过数组特化来管理动态分配的数组,而shared_ptr则需要一些技巧才能安全地管理数组。

C++中智能指针能管理数组吗?探讨unique_ptr数组特化

解决方案

unique_ptr是管理动态数组的首选智能指针,因为它提供了数组特化版本。这意味着你可以使用unique_ptr<t></t>来管理new T[]分配的内存,并在unique_ptr析构时自动调用delete[]释放内存。

C++中智能指针能管理数组吗?探讨unique_ptr数组特化

例如:

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

#include <iostream>
#include <memory>

int main() {
    // 使用 unique_ptr 管理动态分配的 int 数组
    std::unique_ptr<int[]> arr(new int[10]);

    // 初始化数组
    for (int i = 0; i < 10; ++i) {
        arr[i] = i * 2;
    }

    // 访问数组元素
    for (int i = 0; i < 10; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    // 当 arr 超出作用域时,会自动调用 delete[] 释放内存
    return 0;
}

shared_ptr默认情况下不提供数组特化,如果直接用shared_ptr管理数组,在析构时会调用delete而不是delete[],这会导致未定义行为。要让shared_ptr安全地管理数组,你需要提供一个自定义的删除器:

C++14
C++14

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

下载
C++中智能指针能管理数组吗?探讨unique_ptr数组特化
#include <iostream>
#include <memory>

int main() {
    // 使用 shared_ptr 管理动态分配的 int 数组,并提供自定义删除器
    std::shared_ptr<int> arr(new int[10], [](int* p){ delete[] p; });

    // 初始化数组
    for (int i = 0; i < 10; ++i) {
        arr.get()[i] = i * 2; // 注意这里要用 get() 获取原始指针
    }

    // 访问数组元素
    for (int i = 0; i < 10; ++i) {
        std::cout << arr.get()[i] << " ";
    }
    std::cout << std::endl;

    // 当 arr 超出作用域时,会自动调用 delete[] 释放内存
    return 0;
}

需要注意的是,使用shared_ptr管理数组时,不能使用operator[]访问数组元素,必须通过get()获取原始指针,然后才能使用[]访问。

为什么优先选择 unique_ptr 管理数组?

unique_ptr的设计目标是独占资源的所有权,它更轻量级,没有引用计数的开销。对于数组,通常我们希望只有一个所有者,因此unique_ptr更符合这种场景。此外,unique_ptr对数组提供了原生支持,使用起来更安全、更方便,避免了手动编写删除器的麻烦。

shared_ptr 管理数组有什么潜在风险?

虽然可以通过自定义删除器让shared_ptr管理数组,但这种方式存在一些潜在风险:

  • 忘记提供自定义删除器: 如果不小心忘记提供自定义删除器,shared_ptr在析构时会调用delete,导致内存泄漏或程序崩溃。
  • 代码可读性降低: 使用自定义删除器会增加代码的复杂性,降低可读性。
  • 性能开销: shared_ptr需要维护引用计数,这会带来一定的性能开销。

因此,除非有特殊需求(例如,需要在多个地方共享数组的所有权),否则应优先选择unique_ptr管理数组。

如何避免 shared_ptr 管理数组时的错误?

为了避免shared_ptr管理数组时的错误,可以采取以下措施:

  • 始终提供自定义删除器: 确保在使用shared_ptr管理数组时,始终提供自定义删除器,并仔细检查删除器的实现是否正确。
  • 使用工厂函数: 可以编写一个工厂函数来创建shared_ptr,并在工厂函数中设置自定义删除器,这样可以避免在每次创建shared_ptr时都手动设置删除器。
  • 考虑使用 std::vector: 如果数组的大小在运行时才知道,并且需要在多个地方共享数组的所有权,可以考虑使用std::vector。std::vector会自动管理内存,并且提供了方便的数组访问方式。

热门AI工具

更多
Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

WorkBuddy

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

DeepSeek

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

豆包大模型

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

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

相关专题

更多
C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

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

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

3231

2023.11.13

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

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

985

2023.12.29

什么是低代码
什么是低代码

低代码是一种软件开发方法,使用预构建的组件可快速构建应用程序,无需大量编程。想了解更多低代码的相关内容,可以阅读本专题下面的文章。

3331

2024.05.21

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

40

2026.10.28

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

20

2026.10.28

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

40

2026.10.28

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

120

2026.10.22

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

80

2026.10.22

热门下载

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

精品课程

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

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