简体   繁体   English

提升Shared_Ptr分配

[英]Boost Shared_Ptr assignment

Why can I not do this? 为什么我不这样做?

boost::shared_ptr<QueuList> next;

void QueuList::SetNextPtr(QueuList* Next)
{
    boost::mutex mtx;

    boost::mutex::scoped_lock lock(mtx);
    {// scope of lock
        //if (next == NULL)  // is this needed on a shared_ptr??
        next = Next;  // Why can I not assign a raw ptr to a shared_ptr????
    }

} }

How should I do it instead?? 我应该怎么做呢?

EDIT: Calling this method when the next variable is assigned properly, it still causes an error when the QueuList object is destroyed for some reason. 编辑:在正确分配下一个变量时调用此方法,当QueuList对象因某种原因被销毁时仍会导致错误。 I get a debug assertion. 我得到一个调试断言。 The destructor of the object does nothing in particular. 对象的析构函数没有做任何特别的事情。 It only crashes when I call this function: 它只在我调用此函数时崩溃:

    QueuList li;
    QueuList lis;

    li.SetNextPtr(&lis);

When main goes out of scope, I get a debug assertion... Any ideas?? 当main超出范围时,我得到一个调试断言......任何想法?

This is done to prevent accidentally assigning pointers to a shared_ptr whose lifetime is managed independently. 这样做是为了防止意外地将指针分配给其生命周期独立管理的shared_ptr You have to explicitly create a shared_ptr that then takes ownership of the object. 您必须显式创建一个shared_ptr ,然后获取该对象的所有权。

next = boost::shared_ptr<QueueList>( Next );

Edit about your edit The problem is that in your case the shared_ptr takes ownership of an object on the stack. 编辑您的编辑问题是,在您的情况下, shared_ptr获取堆栈上对象的所有权。 Then two things can happen: 然后会发生两件事:

  1. The stack-frame of the object gets cleared before the shared_ptr reaches a reference count of 0. In that case, the shared_ptr will try to delete a non-existing object somewhere later, leading to undefined behavior. shared_ptr达到引用计数0之前,对象的堆栈帧被清除。在这种情况下, shared_ptr将尝试稍后删除某个不存在的对象,从而导致未定义的行为。
  2. The shared_ptr reaches a reference count of 0 before the stack-frame is cleared. 在清除堆栈帧之前, shared_ptr达到引用计数0。 In that case, it will try to delete an object on the stack. 在这种情况下,它将尝试删除堆栈中的对象。 I do not know exactly what happens in that case, but I would assume that it is undefined behavior too. 我不确切知道在这种情况下会发生什么,但我认为它也是未定义的行为。

您可以使用Reset()函数而不是next = boost::shared_ptr<QueueList>(Next);

next.Reset(Next);

Putting a pointer inside a shared_ptr transfers ownership of the pointer to the shared_ptr, so the shared_ptr is responsible for deleting it. 将指针放在shared_ptr会将指针的所有权转移到shared_ptr,因此shared_ptr负责删除它。 This is conceptually an important operation, so the designers of shared_ptr didn't want it to just happen as part of a normal-looking assignment. 这在概念上是一个重要的操作,因此shared_ptr的设计者不希望它只是作为看似正常的赋值的一部分发生。 For example, they wanted to prevent code like: 例如,他们想要阻止代码:

some_shared_ptr = some_other_smart_pointer.get();

which looks fairly innocuous, but would mean that both smart pointers thought they had responsibility for cleaning up the pointer, and would likely double-delete the pointer or something similar. 看起来相当无害,但这意味着两个智能指针都认为他们有责任清理指针,并且可能会双重删除指针或类似的东西。

This is what's happening with your debug assertion. 这就是您的调试断言所发生的事情。 Calling SetNextPtr(&lis) passes ownership of &lis to the shared_ptr , and "ownership" means that the shared_ptr will call delete on its pointee when the last copy of the shared_ptr goes out of scope. 调用SetNextPtr(&lis)通过所有权&lisshared_ptr ,而“所有权”指shared_ptr将调用delete其指针对象时的最后一个副本shared_ptr超出范围。 So you're effectively deleting a local (stack) variable - lis - which corrupts the stack and causes the crash. 所以你有效地删除了一个本地(堆栈)变量 - lis - 它会破坏堆栈并导致崩溃。

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

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