无法理解是什么导致Segmentation Fault

时间:2014-01-24 02:14:47

标签: c++

作为家庭作业的一部分,我必须实施类似于facebook的东西。

以下代码行导致SG:

Tyler->addFriend(302); //Tyler asks Evil to be friends.
Evil->addFriend(1500); //Evil asks Tyler to be friends, resulting in both becoming friends.

以下是执行顺序中的相关方法: [ 1. Tyler通过服务器向Evil发送了一个朋友请求。 2.服务器将好友请求发送给Evil。 3.邪恶想要向泰勒发送朋友请求,但看到泰勒已经向他发送了朋友请求。邪恶接受了朋友的请求。]

void Fan::addFriend(int fanId){
    shared_ptr<FanBookServer> server = FanBookServer::getServer();
    shared_ptr<BaseRequest> request;
    //Check if already friends.
    if (friends.isIn(fanId)){
        throw AlreadyFriendsException();
    }
    //Check if the other fan already send request.
    try {
        request = pendingRequests[fanId];
    } catch (...){
        //Make a friend request and send it to the server.
        auto newRequest = std::make_shared<FriendRequest>(id, fanId);
        server->fanToFanRequest(newRequest);
        return;
    }
    request->accept();  
}

void FanBookServer::fanToFanRequest(std::shared_ptr<BaseRequest> request){
    std::shared_ptr<Fan> srcFan, dstFan;
    try {   
        dstFan = connectedFans[request->getDestination()];
        srcFan = connectedFans[request->getSource()];
    } catch (mtm::MappingDoesntExist&){
        throw UserNotConnectedException();
    }

    try {
        dstFan->pendingRequests.insert(srcFan->getId(), request);
    } catch (mtm::MappingAlreadyExists&){
        throw AlreadySendRequestException();
    }
}

void FriendRequest::accept() {

    std::cout << "About to SG" << std::endl;

    shared_ptr<FanBookServer> server = FanBookServer::getServer();
    server->confirmFriendRequest(getSource(), getDestination());
}

编辑:

我用cout打印我的所有功能,并得出结论,SG在退出FanBookServer :: confirmFriendRequest()后立即发生。

以下cout行:

void FanBookServer::confirmFriendRequest(int sourceFan, int destinationFan){
    std::cout << "Within FanBookServer::confirmFriendRequest" << std::endl;
    std::shared_ptr<Fan> srcFan, dstFan;

    std::cout << "before try" << std::endl;
    try {
        srcFan = connectedFans[sourceFan];
        dstFan = connectedFans[destinationFan];
    } catch (mtm::MappingDoesntExist&){
        throw UserNotConnectedException();
    }
    std::cout << "After try" << std::endl;

    std::cout << "Before insert" << std::endl;
    srcFan->friends.insert(dstFan->getId(), dstFan);
    dstFan->friends.insert(srcFan->getId(), srcFan);
    std::cout << "After insert" << std::endl;
    dstFan->pendingRequests.remove(srcFan->getId());
    std::cout << "After PR" << std::endl;
}

打印的最后一件事是“After PR”。因此,我认为问题的根源是某些共享指针放在范围内。

[EDIT2:] 我运行LLDB并得到以下结果:

* thread #1: tid = 0x11ef4a, 0x0000000100004cea FanBook`std::__1::__shared_ptr_emplace<mtm::FriendRequest, std::__1::allocator<mtm::FriendRequest> >::__on_zero_shared(this=0x0000000100103fd0) + 42 at memory:3741, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x0000000100004cea FanBook`std::__1::__shared_ptr_emplace<mtm::FriendRequest, std::__1::allocator<mtm::FriendRequest> >::__on_zero_shared(this=0x0000000100103fd0) + 42 at memory:3741
   3738 template <class _Tp, class _Alloc>
   3739 void
   3740 __shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared() _NOEXCEPT
-> 3741 {
   3742     __data_.second().~_Tp();
   3743 }
   3744 

我可以帮助我理解这里发生了什么吗?


1 个答案:

答案 0 :(得分:0)

我认为您将srcFan(和destFan)声明为shared_ptr并且您通过

获得其价值,这看起来很可疑
srcFan = connectedFans[sourceFan];

connectedFans中的内容是什么? shared_ptr的数组/向量?或者只是普通指针的数组/向量(我敢打赌就是这种情况)。

如果是后一种情况,则会导致问题:因为srcFan认为它拥有所引用对象的所有权,并且当它超出范围时,它会删除它。然后,当您下次访问connectedFans[sourceFan]时,您正在访问一些释放的内存,这将导致seg错误。

相关问题