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

C++中shared_ptr与对象数组结合使用的问题

关于shared_ptr管理数组的内存泄漏问题解答

先给你明确拆解问题的答案:

1. shared_ptr<A> c(new A[5])确实会导致内存泄漏

当你用new A[5]分配数组时,堆上会开辟容纳5个A对象的连续内存,同时调用每个A的构造函数。但std::shared_ptr的默认删除器用的是delete而非delete[]——delete只会销毁第一个A对象(调用它的析构函数),仅释放该对象的内存,剩下4个A的析构函数不会被触发,它们占用的内存也无法回收,最终造成内存泄漏。

2. C17和C20中的情况

  • C++17之前,std::shared_ptr没有原生支持数组类型,直接写shared_ptr<A>(new A[5])的话,默认删除器依然是delete,泄漏问题依然存在。
  • C++17引入了std::shared_ptr<T[]>的特化版本,如果你把代码改成:
    shared_ptr<A[]> c(new A[5]);
    
    此时shared_ptr的默认删除器会自动使用delete[],正确销毁所有5个A对象并释放整个数组的内存,不会有泄漏。
  • C++20不仅保留了这个特化,还支持用std::make_shared直接创建数组类型的shared_ptr,比如:
    auto c = make_shared<A[]>(5);
    
    这种写法更安全,避免了手动new的风险,同时自动处理数组的正确释放。

3. 自定义删除器的解决方案

如果受限于旧标准无法用shared_ptr<T[]>,你可以像代码里计划的那样传入自定义删除器:

shared_ptr<A> d(new A[5], [](A* ptr){ delete[] ptr; });

这个lambda删除器会在shared_ptr引用计数归零时,调用delete[] ptr,从而正确销毁数组中所有对象并释放全部内存。

最佳实践

  • C17及以后,优先用shared_ptr<T[]>特化版本,或者C20的make_shared<T[]>,它们自动处理数组释放逻辑,不用手动写删除器。
  • 尽量避免直接用new初始化shared_ptr,无论是单个对象还是数组,make_shared系列是更安全的选择,能减少泄漏风险,还能优化内存分配。

内容的提问来源于stack exchange,提问作者Hasan Zeen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:14:37