C++中使用shared_ptr作为函数参数时出现段错误的原因
段错误根因说明
崩溃原因非常直接:你写的baz函数是值传参,函数里改的是参数的局部副本,外层的p自始至终都是空的shared_ptr,最后解引用空指针直接触发段错误,具体逻辑拆解:
- 首先看
main里的定义:LotusPtr p;这行声明的智能指针没有绑定任何对象,默认就是空的,状态和nullptr完全一致,这时候直接写p->m_x就是访问非法空地址,必然崩溃。 - 你本来想通过
a->baz(p)让p指向A对象里创建好的Lotus实例,但baz的形参写的是LotusPtr q,这是值传递:调用函数的时候,会把外层的p拷贝一份生成临时的局部变量q,你在函数里写q = a;只是把这个局部的q重新指向了类里的a成员,等函数执行完毕,局部变量q直接销毁,外层的p没有任何改动,始终是空指针。
修复方式
把baz的形参改成引用传递即可,给参数类型后面加个&:
void baz(LotusPtr& q) { q = a; }
改完之后,函数里的q就是外层传入的p本身,不再是独立副本,赋值之后p会正确指向A实例里的Lotus对象,智能指针的引用计数也会正常维护,后面再访问m_x、m_y就不会出现空指针问题。
额外说明:你代码里
A *a = new A();申请的堆内存没有手动释放,会造成内存泄漏,但这不是本次段错误的触发原因。
内容的提问来源于stack exchange,提问作者liv2hak
相关产品推荐
相关产品推荐

