C++ 共享\u ptr在超出范围时抛出断言

C++ 共享\u ptr在超出范围时抛出断言,c++,boost,shared-ptr,C++,Boost,Shared Ptr,好的,我已经想了一段时间了,但是我不明白,有人能告诉我为什么case#1抛出断言(块类型无效)吗 案例1 mehodName() { //获取此资源的所有从属项 boost::shared_ptr dependents=deactivatedResource->getdependents(); //做点什么 }//此处抛出断言(堆已损坏) 以下是本例中的getDependents: boost::shared_ptr<std::set<std::string>> Res

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

案例1

mehodName()
{
//获取此资源的所有从属项
boost::shared_ptr dependents=deactivatedResource->getdependents();
//做点什么
}//此处抛出断言(堆已损坏)
以下是本例中的getDependents:

boost::shared_ptr<std::set<std::string>> Resource::getDependendents()
{
    return boost::shared_ptr<std::set<std::string>>(&dependents);
}
   std::set<std::string>* Resource::getDependendents()
   {
    return &dependents;
   }
boost::shared_ptr Resource::getDependents()
{
返回提升::共享的ptr(&依赖项);
}
案例2

mehodName()
{
//获取此资源的所有从属项
std::set*dependents=deactivatedResource->getdependents();
}//没问题!!(但是一个明显的漏洞,如果我尝试使用delete,那么与案例1中的断言相同)
以下是本例中的getDependents:

boost::shared_ptr<std::set<std::string>> Resource::getDependendents()
{
    return boost::shared_ptr<std::set<std::string>>(&dependents);
}
   std::set<std::string>* Resource::getDependendents()
   {
    return &dependents;
   }
std::set*Resource::getDependents()
{
返回和家属;
}
对于这两种情况:

std::set<std::string> dependents;
std::设置依赖项;
  • 它是
    dependents
    资源的一个属性吗?
    Resource
    ,看起来boost试图在引用为零时释放非动态内存。在这种情况下,您可以返回一个引用
  • 它依赖于局部变量吗?如果是这样,您应该使用动态内存
  • 更新:

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

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

    在类别声明中:

    boost::shared_ptr<std::set<std::string> > dependents;
    
    boost::共享的ptr依赖项;
    
    在构造函数中:

    Constructor (...) : dependents (new std::set<std::string> ()) { ... }
    
    构造函数(…):依赖项(新std::set()){…} 但在您的情况下,不需要使用动态内存。我建议您返回一个引用而不是指针

  • 它是
    dependents
    资源的一个属性吗?
    Resource
    ,看起来boost试图在引用为零时释放非动态内存。在这种情况下,您可以返回一个引用
  • 它依赖于局部变量吗?如果是这样,您应该使用动态内存
  • 更新:

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

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

    在类别声明中:

    boost::shared_ptr<std::set<std::string> > dependents;
    
    boost::共享的ptr依赖项;
    
    在构造函数中:

    Constructor (...) : dependents (new std::set<std::string> ()) { ... }
    
    构造函数(…):依赖项(新std::set()){…}
    但在您的情况下,不需要使用动态内存。我建议您返回一个引用而不是指针。

    shared\u ptr
    管理资源所有权。当你给它一个指针时,你实际上是在说“这是你的。确保你在超出范围时处理掉它。”1

    但是,然后您向它传递一个指针,该指针不能被释放,因为它指向具有自动存储的对象。这不管用。仅对使用
    new
    创建的指针使用
    shared\u ptr
    。2

    因此,
    shared\u ptr
    正试图
    删除
    尚未
    新建的资源。这将导致您观察到的错误


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


    2还有一个简化:除了
    new
    之外,还有其他方法可以获得需要管理的资源,但是您需要告诉
    shared\u ptr
    如何管理资源。默认的处置操作是
    delete
    ,它只对
    新的
    ed资源有效。

    共享的\u ptr
    管理资源所有权。当你给它一个指针时,你实际上是在说“这是你的。确保你在超出范围时处理掉它。”1

    但是,然后您向它传递一个指针,该指针不能被释放,因为它指向具有自动存储的对象。这不管用。仅对使用
    new
    创建的指针使用
    shared\u ptr
    。2

    因此,
    shared\u ptr
    正试图
    删除
    尚未
    新建的资源。这将导致您观察到的错误


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


    2还有一个简化:除了
    new
    之外,还有其他方法可以获得需要管理的资源,但是您需要告诉
    shared\u ptr
    如何管理资源。默认的处理操作是
    delete
    ,它只对
    new
    ed资源有效。

    实际返回的
    getDependents
    是什么(即该函数的定义是什么)?为什么不一致地使用智能指针?损坏发生在共享的\u ptr超出范围之前。使用一些内存检查,如Valgrind,可能您误解了
    getDependents
    的所有权语义。检查文档和/或代码。@JamesMcNellis编辑的问题,我一直在使用它,使用裸指针,因为共享\u ptr给出的断言失败。@KerrekSB我编写了该方法
    getDependents
    实际返回什么(即该函数的定义做什么)?为什么不一致地使用智能指针?损坏发生在共享的\u ptr超出范围之前。使用一些像Valgrind一样检查过的内存可能你误解了