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

传递std::shared_ptr给子类触发Segmentation fault问题求助

问题根因分析

1. 默认构造函数触发段错误的核心原因

C++ 中类成员的初始化顺序严格按照类定义中声明的先后顺序执行,和初始化列表的书写顺序完全无关:

  • C0 类的成员声明顺序为先定义std::shared_ptr<Dbg> dbg,再定义C1 c1Inst
  • 调用默认构造C0()时执行逻辑如下:
    1. 首先初始化dbg:std::shared_ptr默认构造为空指针
    2. 再执行初始化列表的c1Inst(dbg):把当前为空的dbg传入C1构造函数,C1内部的dbg直接被初始化为空指针
    3. 最后才执行构造函数体内的dbg = std::make_shared<Dbg>(false):这一步仅修改C0自身的dbg指针,已经传递给C1的空指针不会同步更新
  • 后续调用c1Inst.print()时,访问空的dbg指针执行成员函数,直接触发段错误。

2. 你修改后的带参构造仍存在设计缺陷

你修改main函数后调用的C0带参构造,仅初始化了C0自身的dbg指针,没有将该指针传递给内部的c1Inst实例,因此c1Inst会调用自身默认构造函数,生成一个独立的、enabled=false的Dbg实例,既不符合共享同一个日志实例的需求,也不会输出预期的日志内容。

修复方案

仅需调整C0两个构造函数的初始化逻辑即可:

class C0
{
protected:
    std::shared_ptr<Dbg> dbg;
    C1 c1Inst;
public:
    // 默认构造:先初始化dbg,再传递给c1Inst
    C0() : dbg(std::make_shared<Dbg>(false)), c1Inst(dbg) {}
    // 带参构造:将传入的dbg同时传递给内部c1Inst
    C0(std::shared_ptr<Dbg> dbg) : dbg(dbg), c1Inst(dbg) {}

    void run()
    {
        c1Inst.print();
    }
};

修改后两种构造方式都能保证C0和内部C1实例共享同一个Dbg对象,不会出现空指针,也符合日志实例全局复用的设计目标。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:24:04