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

C++如何将shared_ptr变量push_back到shared_ptr类型vector并避免段错误?

认知纠正

你对shared_ptr销毁逻辑的猜测是错误的。std::shared_ptr 通过引用计数管理堆对象生命周期,拷贝shared_ptr时会自动将引用计数+1,销毁shared_ptr实例时引用计数-1,只有引用计数归0时才会释放指向的堆对象。
你把局部变量foo push_back到vector时,实际是将这个shared_ptr拷贝了一份存入vector,此时引用计数变为2;函数退出时局部foo销毁,引用计数减为1,vector里的shared_ptr仍然有效,指向的Foo对象不会被释放。你写的两种push_back写法本身都是合法的,不存在语法或逻辑错误。

段错误的常见原因排查

你的段错误和push_back的写法无关,大概率是以下问题导致的:

  • 下标访问越界:调用otherMethod时,anIndex 的值大于等于 fooVector.size(),超出vector的合法访问范围。
  • 空指针解引用:你用变量存储shared_ptr的场景下,存在分支没有给变量赋值的情况:比如你写的switch逻辑中,如果iProcessorModesParam 既不是PEAKS_MODE也不是RMS_MODE,那么rider 就是空的shared_ptr,push_back到vector后访问时就会触发空指针解引用段错误。
  • 内存重复释放:你手动调用了delete释放了shared_ptr指向的堆对象,导致shared_ptr计数归0时重复释放内存。
  • 多线程竞争:多个线程同时读写存储shared_ptr的vector时没有加锁,导致vector内部结构被破坏。

正确实现建议

你用vector存储shared_ptr<Rider>实现多态的思路是完全正确的,优化写法参考:

  1. 优先使用std::make_shared替代直接new,更安全且性能更优:
std::shared_ptr<Rider> rider;
switch (iProcessorModesParam)
{
    case PEAKS_MODE:
        rider = std::make_shared<PeaksRider>(...);
        break;
    case RMS_MODE:
        rider = std::make_shared<RMSrider>(...);
        break;
    default:
        // 补齐默认分支处理,避免rider为空
        rider = std::make_shared<DefaultRider>(...);
        // 或者直接抛出异常/跳过push_back,避免空指针存入vector
}
volumeRiders.push_back(rider);
  1. 访问vector元素前增加合法性检查,避免异常:
void Bar::otherMethod()
{
    if (anIndex < fooVector.size() && fooVector[anIndex] != nullptr) {
        fooVector[anIndex]->baz();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:15:06