简体   繁体   English

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

[英]C++: Error when copying from *std::shared_ptr

I have a function that returns a shared pointer to an object (it is difficult to include the MyObject definition because of many large dependencies): 我有一个函数返回一个指向对象的共享指针(由于许多大的依赖项,很难包含MyObject定义):

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

Does anyone know why this code works: 有谁知道为什么这段代码有效:

Case 1: no errors with valgrind -v --tool=memcheck 案例1: valgrind -v --tool=memcheck没有错误

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

While this code crashes: 虽然此代码崩溃:

Case 2: crashes and gives several errors with valgrind -v --tool=memcheck 案例2:使用valgrind -v --tool=memcheck崩溃并发出几个错误

MyObject obj = *f("hello");

The MyObject class has a working assignment operator and copy constructor (both verified in Case 1 ). MyObject类有一个工作赋值运算符和复制构造函数(在案例1中都进行了验证)。

I have also tried creating a std::shared_ptr<MyObject> (via f ), copying that to a pointer, copying the pointer to an object on the stack, and deleting the pointer. 我还尝试创建一个std::shared_ptr<MyObject> (通过f ),将其复制到指针,将指针复制到堆栈上的对象,并删除指针。 The final object on the stack is still fine: 堆栈上的最终对象仍然很好:

Case 3: no errors with valgrind -v --tool=memcheck 案例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();

Is the error perhaps because std::shared_ptr is created as an rvalue, and frees its memory as soon as the * operator runs? 错误可能是因为std::shared_ptr被创建为rvalue,并在*运算符运行后立即释放其内存?

The problem is (almost certainly) that you're shallow-copying one of the members of MyObject in its copy constructor. 问题是(几乎可以肯定)你在其复制构造函数中浅层复制MyObject一个成员。 Then you either try to access the shallow data that's no longer valid, or you double delete it. 然后,您要么尝试访问不再有效的浅层数据,要么双重删除它。

Consider the cases: In the first and third cases, the very first object from which all copies are made is still alive when you act on the stack object. 考虑这些情况:在第一种和第三种情况下,当您对堆栈对象进行操作时,制作所有副本的第一个对象仍然存在。 In the second case the shared_ptr goes away after the copy construction, invoking the destructor of MyObject . 在第二种情况下, shared_ptr在复制构造之后消失,调用MyObject的析构函数。

If you changed the third case thusly, I suspect it would crash: 如果你这样改变了第三种情况,我怀疑它会崩溃:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM