提升Shared_Ptr分配

时间:2010-09-30 09:26:31

标签: c++ pointers boost

为什么我不这样做?

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????
    }

}

我应该怎么做呢?

编辑:在正确分配下一个变量时调用此方法,当QueuList对象因某种原因被销毁时仍会导致错误。我得到一个调试断言。对象的析构函数没有做任何特别的事情。当我调用这个函数时它只会崩溃:

    QueuList li;
    QueuList lis;

    li.SetNextPtr(&lis);

当主要超出范围时,我得到一个调试断言......任何想法?

3 个答案:

答案 0 :(得分:7)

这样做是为了防止意外地将指针分配给其生命周期独立管理的shared_ptr。您必须明确创建shared_ptr,然后获取对象的所有权。

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

编辑您的编辑问题在于,在您的情况下,shared_ptr获取堆栈中对象的所有权。然后会发生两件事:

  1. shared_ptr达到引用计数0之前,对象的堆栈帧被清除。在这种情况下,shared_ptr将尝试稍后删除某个不存在的对象,从而导致未定义的行为。
  2. 在清除堆栈帧之前,shared_ptr达到引用计数0。在这种情况下,它将尝试删除堆栈中的对象。我不确切知道在这种情况下会发生什么,但我认为它也是未定义的行为。

答案 1 :(得分:6)

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

next.Reset(Next);

答案 2 :(得分:5)

将指针放在shared_ptr内会将指针的所有权转移到shared_ptr,因此shared_ptr负责删除它。这在概念上是一项重要的操作,因此shared_ptr的设计者不希望它只是作为看似正常的作业的一部分而发生。例如,他们想要阻止代码:

some_shared_ptr = some_other_smart_pointer.get();

看起来相当无害,但这意味着两个智能指针都认为他们有责任清理指针,并且可能会双重删除指针或类似的东西。

这是您的调试断言发生的事情。致电SetNextPtr(&lis)会将&lis的所有权转让给shared_ptr,而“所有权”意味着shared_ptr会在最后一个副本上调用deleteshared_ptr超出了范围。所以你实际上删除了一个本地(堆栈)变量 - lis - 这会破坏堆栈并导致崩溃。