if(mySharedPtr)导致信号11?

时间:2014-04-18 00:09:23

标签: c++ android-ndk segmentation-fault smart-pointers

不知何故,在没有解除引用的情况下访问shared_ptr会在Android上导致信号11(SIGSEGV)。

我在run()中有一个A功能,可以获取B实例的锁定并调用B::top()A只有一个实例。 A有其他线程可能调用的其他公共方法来修改mB(因此是互斥锁),但它们还没有被任何东西调用。

LogCat错误:

  

04-17 15:15:16.903:A / libc(11591):致命信号11(SIGSEGV)位于0x00000024(代码= 1)

在课程A中:

std::thread mControllerThread;
std::mutex mBMutex;
shared_ptr<B> mB;

A() {  
    mB.reset( new B() ); 
    mControllerThread = std::thread( std::bind(&A::run, this) );       
}

//...

void run() {
    std::unique_lock<std::mutex > lk(mBMutex);
    shared_ptr<const Event> event = mB->top(B::Scope::FUTURE);
}

在课程B中:

shared_ptr<EventHeap> mFuture;

B() {
    mFuture.reset( new EventHeap() );
}

//...

shared_ptr<const Event> top(Scope scope, int mask=EVENT_MASK_SUPPORTED) const {
    shared_ptr<const Event> event;

    if(scope == Scope::PAST) {
        //...
    } else if(scope == Scope::FUTURE) {
        LOGD(LOG_TAG, "Testing mFuture ptr");
        // Fails here with any of these versions
        if(mFuture) {
        // if(mFuture.get() != NULL) {
        // if(mFuture != nullptr) {
            LOGD(LOG_TAG, "Getting top from FUTURE");
            event = mFuture->top(mask);
        } else {
            LOGE(LOG_TAG, "mFuture is null");
        }
    }
    return event;
}

那么如何在不解除引用的情况下访问智能指针可能会导致段错误?谢谢!

1 个答案:

答案 0 :(得分:0)

如果使用非空指针初始化shared_ptr,则指向的语句。

if(mFuture) // can be seen as if(mFuture.privateMember_Ptr != nullptr)

很明显,指针本身没有被解引用,但是访问了指针的值。所以这个内存位置似乎无效。现在这个内存位置在哪里?它是mFuture的一部分,它本身就是B的一部分。让我们重写mFuture来展示我们真正取消引用的内容:

if(this->mFuture.privateMember_Ptr != nullptr)

似乎&#34;这&#34;如果无效,您可以先在top方法中打印,然后&#34;展开&#34;具有相同调试的堆栈。看看来源,&#34;这个&#34;应该对应于A类中的mB。因此,您可以在调用B :: top()之前在A :: run()中打印mB。 mB在A&#39;中用新的B()&#34;初始化。你检查这个内存分配成功的地方吗? (Android AFAIK上默认禁用例外,因此new可以返回nullptr)