C ++:从* std :: shared_ptr复制时出错

时间:2012-05-09 22:16:11

标签: c++ c++11 valgrind shared-ptr

我有一个返回指向对象的共享指针的函数(由于许多大的依赖项,很难包含MyObject定义):

std::shared_ptr<MyObject> f(std::string params)
{
  return std::shared_ptr<MyObject>(new MyObject(params));
}

有谁知道为什么这段代码有效:

案例1:valgrind -v --tool=memcheck

没有错误
std::shared_ptr<MyObject> obj_ptr = f("hello");
MyObject obj = *obj_ptr;

这段代码崩溃了:

案例2:因valgrind -v --tool=memcheck

而崩溃并出现多个错误
MyObject obj = *f("hello");

MyObject类有一个工作赋值运算符和复制构造函数(都在案例1 中验证)。

我还尝试创建std::shared_ptr<MyObject>(通过f),将其复制到指针,将指针复制到堆栈上的对象,然后删除指针。堆栈上的最终对象仍然很好:

案例3:valgrind -v --tool=memcheck

没有错误
std::shared_ptr<MyObject> obj_ptr = f("hello");
MyObject * obj_ptr2 = new MyObject(*obj_ptr);
MyObject obj3 = *obj_ptr2;
delete obj_ptr2;
obj3.print();

错误可能是因为std::shared_ptr被创建为右值,并在*运算符运行后立即释放其内存吗?

1 个答案:

答案 0 :(得分:8)

问题是(几乎可以肯定)你在其拷贝构造函数中复制了MyObject的一个成员。然后,您要么尝试访问不再有效的浅层数据,要么双重删除它。

考虑案例: 在第一种和第三种情况下,当您对堆栈对象执行操作时,制作所有副本的第一个对象仍然处于活动状态。在第二种情况下,shared_ptr在复制构造后消失,调用MyObject的析构函数。

如果你因此改变了第三种情况,我怀疑它会崩溃:

MyObject * obj_ptr2 = new MyObject("hello");
MyObject obj3 = *obj_ptr2;
delete obj_ptr2;
obj3.print();