shared_ptr在超出范围时抛出断言

时间:2012-03-10 22:39:34

标签: c++ boost shared-ptr

好的,我一直试图绕过这个问题一段时间,但我不明白,有人可以告诉我为什么案例#1会抛出一个断言(BLOCK TYPE IS INVALID)?

案例#1

mehodName()
{
    // Get all dependents for this resource
    boost::shared_ptr<std::set<std::string>> dependents = deactivatedResource->getDependendents();
    // Do some stuff 
} // Assertion thrown here (heap gets corrupted)

在这种情况下,这是getDependents:

boost::shared_ptr<std::set<std::string>> Resource::getDependendents()
{
    return boost::shared_ptr<std::set<std::string>>(&dependents);
}

案例#2

mehodName()
{
// Get all dependents for this resource
std::set<std::string>* dependents = deactivatedResource->getDependendents();
} // No problem !! (but an obvious leak , if I try to use delete ,then the same assertion as in case 1)

在这种情况下,这是getDependents:

   std::set<std::string>* Resource::getDependendents()
   {
    return &dependents;
   }

对于这两种情况:

std::set<std::string> dependents;

2 个答案:

答案 0 :(得分:6)

shared_ptr管理资源所有权。当你传递一个指针时,你实际上在说“这是你的。当你超出范围时,请务必将其丢弃。“ 1

然后你传递一个指针,该指针必须不被处理,因为它指向具有自动存储的对象。这不起作用。仅对使用shared_ptr创建的指针使用new 2

因此,shared_ptr正在尝试delete尚未new的资源。这会导致您观察到的错误。


1 这是一个简化。实际上,shared_ptr管理共享所有权(=与其他shared_ptr实例共享);这意味着一旦所有拥有shared_ptr超出范围,资源将被处理掉。

2 同样是一种简化:除new之外还有其他方法可以获取需要管理的资源,但是您需要告诉shared_ptr 如何< / em>来管理资源。默认处理操作为delete,仅适用于new资源。

答案 1 :(得分:2)

  1. 它是dependents属性Resource ?,看起来boost正在尝试在引用变为零时释放非动态内存。在这种情况下,您可以返回引用。
  2. 它是否依赖于局部变量?如果是这样,你应该使用动态内存。
  3. 更新

    然后在您的情况下,返回共享指针没有意义,因为尚未动态创建对象dependents

    在任何情况下,如果您需要动态创建它,您应该执行以下操作:

    在班级宣言中:

    boost::shared_ptr<std::set<std::string> > dependents;
    

    在构造函数中:

    Constructor (...) : dependents (new std::set<std::string> ()) { ... }
    

    但在您的情况下,不需要使用动态内存。我建议你返回一个引用而不是一个指针。