shared_ptr在超出范围时抛出断言

shared_ptr throwing assert when it goes out of scope

本文关键字:范围 断言 ptr shared      更新时间:2023-10-16

好吧,我已经想了一段时间了,但我不明白,有人能告诉我为什么案例#1抛出断言(块类型无效)吗?

案例#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;

shared_ptr管理资源所有权。当你递给它一个指针时,你实际上是在说"这是你的。当你超出范围时,一定要处理掉它。"1

但随后您向它传递了一个指针,该指针不能被丢弃,因为它指向的是具有自动存储的对象。这行不通。仅对使用new创建的指针使用shared_ptr2

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


1这是一种简化。实际上,shared_ptr管理共享的所有权(=与其他shared_ptr实例共享);这意味着只有当所有拥有shared_ptr都超出范围时,才会处理该资源。

2还有一个简化:除了new,还有其他方法可以获得需要管理的资源,但您需要告诉shared_ptr如何管理资源。默认的处置操作是delete,它仅适用于new ed资源。

  1. CCD_ 14是CCD_?,当引用为零时,boost似乎试图解除分配非动态内存。在这种情况下,您可以返回一个引用
  2. 它依赖于局部变量吗?如果是这样,您应该使用动态内存

更新:

那么在您的情况下,返回共享指针是没有意义的,因为对象dependents不是动态创建的。

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

在类声明中:

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

在构造函数中:

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

但在您的情况下,没有必要使用动态内存。我建议您返回引用而不是指针。