如何解决智能指针访问类内定义结构体时出现的崩溃问题
问题原因分析
- 代码中定义的
std::shared_ptr<CTest::StructTest> opt为默认初始化的智能指针,其内部存储的原生指针值为nullptr,没有指向任何实际存在的CTest::StructTest类实例。 - 后续执行
opt->StrTest赋值操作时,本质是对空指针进行解引用,属于C++标准明确定义的未定义行为,运行时崩溃是这类错误的典型表现,和智能指针本身的功能无关。
解决方法
只要在使用智能指针前,让其关联合法的对象实例即可,有两种常用实现方案:
方案1:使用std::make_shared创建实例(推荐)
std::make_shared会在堆上一次性完成对象内存和智能指针控制块的分配,异常安全性更高,是初始化智能指针的首选方式。
修正后完整代码如下:
#include <iostream> #include <memory> class CTest { public: struct StructTest { std::string StrTest; }; }; int main() { // 初始化智能指针的同时创建关联的对象实例 std::shared_ptr<CTest::StructTest> opt = std::make_shared<CTest::StructTest>(); opt->StrTest = "hello world\n"; std::cout << opt->StrTest; return 0; }
方案2:使用reset方法关联手动分配的实例
如果需要手动接管new出来的对象,可以调用shared_ptr的reset方法传入原生指针:
int main() { std::shared_ptr<CTest::StructTest> opt; // 手动分配对象并交给智能指针管理生命周期 opt.reset(new CTest::StructTest()); opt->StrTest = "hello world\n"; std::cout << opt->StrTest; return 0; }
注意:不推荐手动
new对象传入智能指针的写法,一方面会产生两次独立内存分配(对象+控制块),性能弱于std::make_shared;另一方面如果分配控制块时抛出异常,会导致new出来的对象无法被回收,存在内存泄漏风险。
内容的提问来源于stack exchange,提问作者dearwangsen
相关产品推荐
相关产品推荐

