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>实现多态的思路是完全正确的,优化写法参考:
- 优先使用
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);
- 访问vector元素前增加合法性检查,避免异常:
void Bar::otherMethod() { if (anIndex < fooVector.size() && fooVector[anIndex] != nullptr) { fooVector[anIndex]->baz(); } }
内容的提问来源于stack exchange,提问作者clickbait
相关产品推荐
相关产品推荐

