【问题标题】:Why is my program crashing in boost::enable_shared_from_this<>/boost::shared_ptr<>?为什么我的程序在 boost::enable_shared_from_this<>/boost::shared_ptr<> 中崩溃?
【发布时间】:2013-04-10 05:59:22
【问题描述】:

我正在尝试找出程序在 shared_ptr 中崩溃的原因。

#0  0x00007fff90723212 in __pthread_kill ()
#1  0x00007fff93415b54 in pthread_kill ()
#2  0x00007fff93459dce in abort ()
#3  0x00007fff8a0519eb in abort_message ()
#4  0x00007fff8a04f39a in default_terminate ()
#5  0x00007fff930bf887 in _objc_terminate ()
#6  0x00007fff8a04f3c9 in safe_handler_caller ()
#7  0x00007fff8a04f424 in std::terminate ()
#8  0x00007fff8a05058b in __cxa_throw ()
#9  0x0000000100057cbc in boost::throw_exception<boost::bad_weak_ptr> (e=@0x1002c5b88) at throw_exception.hpp:66
#10 0x0000000100057bf4 in boost::detail::shared_count::shared_count (this=0x1002c5d00, r=@0x100304180) at shared_count.hpp:509
#11 0x0000000100057b7d in boost::detail::shared_count::shared_count (this=0x1002c5d00, r=@0x100304180) at shared_count.hpp:511
#12 0x000000010004ad14 in boost::shared_ptr<myns::(anonymous namespace)::MySharedFromThisClass>::shared_ptr<myns::(anonymous namespace)::MySharedFromThisClass> (this=0x1002c5cf8, r=@0x100304178) at shared_ptr.hpp:220
#13 0x000000010004acad in boost::shared_ptr<myns::(anonymous namespace)::MySharedFromThisClass>::shared_ptr<myns::(anonymous namespace)::MySharedFromThisClass> (this=0x1002c5cf8, r=@0x100304178) at shared_ptr.hpp:223
#14 0x000000010004a9b4 in boost::enable_shared_from_this<myns::(anonymous namespace)::MySharedFromThisClass>::shared_from_this (this=0x100304178) at enable_shared_from_this.hpp:49

MySharedFromThisClass 定义为:

class MySharedFromThis : public boost::enable_shared_from_this<MySharedFromThis> {
    // ....
};

传递的实例定义如下:

auto myKlass = std::make_shared<MySharedFromThis>();

并通过以下方式复制:

void myFunction(::boost::shared_ptr<MySharedFromThis> myKlass) {
  myFunction(shared_from_this());
}

什么给了?一切都在编译时没有警告或错误,但事情很明显以不那么愉快的方式出现了段错误。

【问题讨论】:

    标签: c++ boost c++11 shared-ptr


    【解决方案1】:

    我发布我自己的答案是因为这段代码编译时没有任何警告或错误,并且花费了相当多的精力来追踪。

    从上面的例子看这一行应该很明显:

    auto myKlass = std::make_shared<MySharedFromThis>();
    

    myKlass 的类型是 std::shared_ptr&lt;MySharedFromThis&gt;,而不是 boost::shared_ptr&lt;MySharedFromThis&gt;。将std::make_shared&lt;&gt; 更改为boost::make_shared&lt;&gt;,一切都按预期/预期工作。

    导致此崩溃的可能原因有两种:

    1. 在 myFunction() 中对 shared_from_this() 的调用在没有现有 ::boost::shared_ptr&lt;&gt; 的情况下被调用。相反,所发生的是创建了一个std::shared_ptr&lt;&gt;,它具有与boost::shared_ptr&lt;&gt; 不同的ABI。值得注意的是,libboost_thread-mt.dylib 需要 boost::enable_shared_from_this&lt;&gt; 类而不是 std::enable_shared_from_this&lt;&gt; 类。
    2. 根据enable_shared_from_this<> documentation,不满足先决条件。

      要求:enable_shared_from_this 必须是 T 的可访问基类。 *this 必须是 T 类型的实例 t 的子对象。必须至少存在一个拥有 t 的 shared_ptr 实例 p。

      实际上发生的是std::shared_ptr&lt;&gt; 实例,但没有boost::shared_ptr&lt;&gt; 实例。

    至少这是我对正在发生的事情的理解。我认为 #1 是导致段错误的真正问题,而 #2 迟早会成为问题(尽管我并不完全相信)。

    【讨论】:

    • ABI 在这里不是问题。正如预期的那样,您只会得到bad_weak_ptr 异常,但不要捕获它,因此线程(和进程)终止。
    • 使用enable_shared_from_this&lt;&gt; 导致此异常的常见原因是在共享对象的构造函数中调用shared_form_this() - 如果您想将对象传递给构造函数的指针,这并不常见其聚合成员。巧妙的解决方案是将您的构造函数声明为私有并提供工厂方法,您可以在其中使用 shared_form_this() 并放弃同性恋。
    猜你喜欢
    • 1970-01-01
    • 2010-12-21
    • 2012-05-20
    • 2012-03-22
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    • 2020-10-03
    • 1970-01-01
    相关资源
    最近更新 更多