You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用std::shared_ptr管理动态数组的技术问题求助

解决std::shared_ptr管理动态数组的那些坑

嘿,我太懂你从普通指针转智能指针时遇到的这些糟心事了!当初我刚上手shared_ptr管理数组的时候,也踩过一模一样的雷,咱们一个个拆解问题,再给你靠谱的解决方案:

先说说你遇到的三个问题的根源

1. std::shared_ptr<Entity> f1(new Entity[100])编译报错

你用的是非数组特化版的shared_ptr,它本身没有重载[]运算符,所以你想直接用f1[i].print()肯定编译不过。而且更隐蔽的问题是:这个shared_ptr默认的删除器是delete,不是delete[],就算你强行用f1.get()[i].print()能编译,最后销毁的时候也会因为用错删除器导致内存泄漏或者未定义行为。

2. std::make_shared<int>(100)访问f1.get()[1]触发内存错误

这里完全是理解错了make_shared的用法!std::make_shared<int>(100)是创建单个int对象,值为100,不是创建一个包含100个int的数组。你用get()[1]相当于访问单个int对象后面的内存,直接越界,不出错才怪。

3. std::shared_ptr<Entity[]> f1 = std::make_shared<Entity[]>(new Entity[100])报错

make_shared<Entity[]>的参数是数组的元素个数,不是你手动new出来的指针!它的作用就是帮你自动分配数组内存,不需要你自己写new,你传new Entity[100]完全是画蛇添足,类型不匹配自然报错。

正确实现动态数组管理的方式(C++17+推荐)

从C++17开始,标准库提供了std::shared_ptr<T[]>的数组特化版本,完美适配动态数组场景:它支持[]运算符,默认删除器是delete[],用法和普通指针的动态数组几乎一致。

管理自定义类型(比如Entity)的数组

// 方式1:用make_shared创建(推荐,更安全,避免内存泄漏)
std::shared_ptr<Entity[]> f1 = std::make_shared<Entity[]>(100);
// 这里的100是数组元素个数,make_shared会自动分配并初始化100个Entity对象
f1[0].print(); // 直接用[]访问元素,和普通指针一样
f1[99].print(); // 访问最后一个元素也没问题

// 方式2:直接用new初始化(不推荐,不如make_shared安全)
std::shared_ptr<Entity[]> f1(new Entity[100]);
f1[5].print(); // 同样可以正常调用成员方法

管理内置类型(比如int)的数组

// 创建包含100个int的数组,默认值是0
std::shared_ptr<int[]> f1 = std::make_shared<int[]>(100);
f1[1] = 42; // 给第二个元素赋值
std::cout << f1[1] << std::endl; // 正常输出42,不会触发内存错误

如果你还在使用C++17之前的版本

那只能手动指定删除器来处理数组,写法会麻烦一点,但也能实现需求:

// 自定义删除器,用delete[]销毁数组
std::shared_ptr<Entity> f1(new Entity[100], [](Entity* ptr) { delete[] ptr; });
// 访问元素时需要先调用get()拿到原始指针,再用[]
f1.get()[0].print();

不过还是建议尽量升级到C++17及以后的版本,数组特化版的shared_ptr用起来舒服太多了。

内容的提问来源于stack exchange,提问作者Claudiu Andries

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 07:38:12