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

为何使用shared_ptr的简单C++程序出现段错误?

为什么使用shared_ptr的C++程序会出现段错误?

问题描述

这段使用std::shared_ptr<char[]>的C++程序运行时出现段错误,但换成std::unique_ptr<char[]>就正常。是不是因为不该用std::make_shared<char[]>(BLOCKSIZE)初始化block?

代码如下:

#include <memory>
#include <iostream>

#define BLOCKSIZE 100000

struct MyClass {
    std::shared_ptr<char[]> block;

    MyClass() : block(std::make_shared<char[]>(BLOCKSIZE)) {}

    void fill_block() {
        for (size_t i = 0; i < BLOCKSIZE; ++i) {
            block[i] = static_cast<char>(i % 99);
        }
    }

    void print_one(size_t i) {
        if (i < BLOCKSIZE) {
            std::cout << static_cast<int>(block[i]);
        } else {
            std::cout << "Index out of range!";
        }
    }
};

int main() {
    for (size_t i = 0; i < 1000; ++i) {
        MyClass x;
        x.fill_block();
        x.print_one(i);
    }

  return 0;
}

运行命令及结果:

g++ shared_ptr_test.cpp -o shared_ptr_test
./shared_ptr_test
Segmentation fault

原因分析

核心问题是C++版本兼容性:

  • std::unique_ptr<T[]>从C++11开始就原生支持数组类型,配套的数组操作(比如operator[])和正确的删除器(自动调用delete[])都是合规的。
  • 但std::shared_ptr<T[]>以及数组版本的std::make_shared<T[]>是C17才引入的特性。如果你的编译器默认使用C17之前的标准(比如g默认用C14),那么std::shared_ptr<char[]>和std::make_shared<char[]>属于未定义行为:
    • 老版本的shared_ptr不识别数组类型,会用默认的删除器(调用delete而非delete[])来释放内存,这会导致内存泄漏或堆损坏。
    • 同时,operator[]对于C++17之前的shared_ptr<T[]>也不是标准支持的操作,访问block[i]会触发非法内存访问,最终导致段错误。

解决方法

有两种可行的修复方案:

  1. 升级编译标准到C++17及以上:
    编译时添加-std=c++17参数,让编译器支持shared_ptr的数组特性:

    g++ shared_ptr_test.cpp -o shared_ptr_test -std=c++17
    

    这样std::make_shared<char[]>和shared_ptr<char[]>::operator[]都会按标准工作,不会出现段错误。

  2. 在C++17之前的标准下手动指定删除器:
    如果无法升级C++版本,不要用make_shared<char[]>,而是手动创建数组并指定正确的删除器:

    MyClass() : block(new char[BLOCKSIZE], std::default_delete<char[]>()) {}
    

    这样shared_ptr会用delete[]释放数组内存,同时operator[]虽然不是标准支持,但很多编译器(比如g++)会提供扩展支持,能正常访问数组元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 05:27:15