C++ 对已删除对象调用了deadline\u计时器回调

C++ 对已删除对象调用了deadline\u计时器回调,c++,boost-asio,C++,Boost Asio,在流动的代码中,即使我从boost::enable_shared_this继承了net类,当net被删除时,OnTimer仍然会再次被无效对象调用。如何解决这个问题?提前谢谢 boost::shared_ptr<boost::asio::io_service> service = boost::make_shared<boost::asio::io_service>(); class net:public boost::enable_shared_from_this&l

在流动的代码中,即使我从boost::enable_shared_this继承了net类,当net被删除时,OnTimer仍然会再次被无效对象调用。如何解决这个问题?提前谢谢

boost::shared_ptr<boost::asio::io_service> service =
boost::make_shared<boost::asio::io_service>();

class net:public boost::enable_shared_from_this<net>
{
 public:
    net(boost::shared_ptr<boost::asio::io_service>& service);
    void StartTimer();
    void OnTimer(const boost::system::error_code& e);
    ~net();
 private:
    boost::asio::deadline_timer timer_;
    int a;
};

net::net(boost::shared_ptr<boost::asio::io_service>& service)
    :timer_(*service, boost::posix_time::milliseconds(1000))
{
}

net::~net()
{
    timer_.cancel();
}

void net::StartTimer()
{
    timer_.async_wait(boost::bind(&net::OnTimer, 
        shared_from_this(), boost::asio::placeholders::error));
}

void net::OnTimer(const boost::system::error_code& e)
{
    a = 10;
    timer_.async_wait(boost::bind(&net::OnTimer, 
        shared_from_this(), boost::asio::placeholders::error));
}

unsigned int WINAPI ThreadMain(void* arg)
{
    boost::shared_ptr<net> ptr(new net(service));
    ptr->StartTimer();
    Sleep(5000);
    boost::shared_ptr<net> invalid_ptr;
    ptr = invalid_ptr;
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    boost::shared_ptr<boost::asio::io_service::work> io_service_work =
        boost::make_shared<boost::asio::io_service::work>(*service);

    boost::system::error_code ec;
    HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadMain, NULL, 0, NULL);
    if (hThread == NULL)
    {
        return -1;
    }
    boost::shared_ptr<boost::thread> thread_ = 
        boost::make_shared<boost::thread>(boost::bind(&boost::asio::io_service::run, service.get(), ec));

// in order to make sure OnTimer can be called at least once
    Sleep(2000);
    boost::shared_ptr<boost::asio::io_service::work>  invalid_ptr;
    io_service_work = invalid_ptr;
    thread_->join();
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    return 0;
}
boost::共享ptr服务=
boost::使_共享();
类net:public boost::从\u中启用\u共享\u
{
公众:
net(boost::共享存储和服务);
void StartTimer();
void OnTimer(const boost::system::error\u code&e);
~net();
私人:
boost::asio::截止时间\u计时器\uu;
INTA;
};
net::net(boost::共享存储和服务)
:timer_uu(*服务,boost::posix_时间::毫秒(1000))
{
}
net::~net()
{
计时器u0.cancel();
}
void net::StartTimer()
{
计时器异步等待(boost::bind(&net::OnTimer,
共享_from_this(),boost::asio::placeholders::error));
}
void net::OnTimer(const boost::system::error\u code&e)
{
a=10;
计时器异步等待(boost::bind(&net::OnTimer,
共享_from_this(),boost::asio::placeholders::error));
}
无符号int-WINAPI-ThreadMain(void*arg)
{
boost::shared_ptr ptr(新网络(服务));
ptr->StartTimer();
睡眠(5000);
boost::共享\u ptr无效\u ptr;
ptr=无效的ptr;
返回0;
}
int _tmain(int argc,_TCHAR*argv[]
{
boost::共享\u ptr io\u服务\u工作=
boost::使_共享(*服务);
boost::system::error_code ec;
HANDLE hThread=(HANDLE)u beginthreadex(NULL,0,ThreadMain,NULL,0,NULL);
if(hThread==NULL)
{
返回-1;
}
boost::共享线程
boost::make_shared(boost::bind(&boost::asio::io_service::run,service.get(),ec));
//为了确保至少可以调用OnTimer一次
睡眠(2000年);
boost::共享\u ptr无效\u ptr;
io\服务\工作=无效\ ptr;
线程->连接();
WaitForSingleObject(hThread,无限);
CloseHandle(hThread);
返回0;
}

您正在使用boost::asio::placeholders::error设置对OnTimer的回调,但忽略其错误代码。您应该真正获取并使用此错误代码,否则您将访问已删除的
net
实例的成员(变量
a
计时器
):


@伊戈尔。这正是他案例中出现的错误代码。
void net::OnTimer(const boost::system::error_code& e)
{
    if( e == boost::asio::error::operation_aborted ) return; //Do nothing if timer is cancelled
    if( e ) return; //Do nothing in case of error
    a = 10;
    timer_.async_wait(boost::bind(&net::OnTimer, 
        shared_from_this, boost::asio::placeholders::error));
}