std :: vector :: erase()(多线程)'断言'px!= 0'失败.

cof*_*ean 2 c++ boost stl shared-ptr boost-asio

shared_ptr相似,断言px!= 0失败

我正在编写一个游戏服务器,它会生成一个新线程来处理每个用户会话.主线程有一个UserSession共享指针的std :: vector.另一个线程定期从此向量中删除死会话但在执行std :: vector :: erase()时失败.我无法找出生活中的错误.

错误是:

Prototype2:/usr/include/boost/smart_ptr/shared_ptr.hpp:653:typename boost :: detail :: sp_member_access :: type boost :: shared_ptr :: operator - >()const [with T = UserSession; typename boost :: detail :: sp_member_access :: type = UserSession*]:断言`px!= 0'失败.中止(核心倾倒)

相关代码是:

void GameServer::start()
{
    int sessionid;
    boost::asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port_));
    boost::thread(&GameServer::session_monitor, this);

    for (;;)
    {   
        socket_shptr socket(new tcp::socket(io_service));
        acceptor.accept(*socket);
        sessionid = numsessions_++;
        UserSession* usession = new 
            UserSession(socket, sessionid, io_service);
        session_shptr session(usession);

        sessions_mutex_.lock();
        sessions_.push_back(session);
        sessions_mutex_.unlock();

        std::cout << "Starting session for client " <<
            get_client_ip(*socket) << std::endl;

        session->start();
    }   
}

void GameServer::session_monitor()
{
    for (;;)
    {   
        boost::this_thread::sleep(boost::posix_time::seconds(10));
        std::cout << "Removing dead user sessions" << std::endl;

        sessions_mutex_.lock();
        for (std::vector<session_shptr>::iterator it = sessions_.begin();
            it != sessions_.end(); ++it)
        {
            if ((*it)->is_dead())
            {
                std::cout << "Removing session: " << (*it)->id() <<
                    std::endl;

                sessions_.erase(it);
            }
        }
        sessions_mutex_.unlock();
    }
}
Run Code Online (Sandbox Code Playgroud)

Dar*_*con 5

调用erase迭代器会使它失效.然后,您尝试继续使用它来遍历列表.您需要使用返回值erase继续遍历列表.

    for (std::vector<session_shptr>::iterator it = sessions_.begin(); it != sessions_.end(); )
    {
        if ((*it)->is_dead())
        {
            std::cout << "Removing session: " << (*it)->id() <<
                std::endl;

            it = sessions_.erase(it);
        }
        else
          ++it;
    }
Run Code Online (Sandbox Code Playgroud)