我试图做一些我认为很常见的事情,但我遇到了一些问题。
我正在使用boost asio,并尝试创建TCP服务器。我接受与async_accept的连接,并创建共享指针。我有一个长期存在的对象(如连接管理器),它将shared_ptr插入到一个集合中。这是一个片段:
std::shared_ptr<WebsocketClient> ptr = std::make_shared<WebsocketClient>(std::move(s));
directory.addPending(ptr);
ptr->onConnect(std::bind(&Directory::addClient, &directory, std::placeholders::_1));
ptr->onDisconnect(std::bind(&Directory::removeClient, &directory, std::placeholders::_1));
ptr->onMessage(std::bind(&Directory::onMessage, &directory, std::placeholders::_1, std::placeholders::_2));
ptr->start();
目录有std::set<std::shared_ptr<WebsocketClient>> pendingClients;
添加客户端的功能是:
void Directory::addPending(std::shared_ptr<WebsocketClient> ptr){
std::cout << "Added pending client: " << ptr->getName() << std::endl;
pendingClients.insert(ptr);
}
现在,当WebsocketClient启动时,它尝试使用shared_from_this()创建shared_ptr,然后启动async_read_until(&#34; \ r \ n \ r \ n \ n&#34;),并将该shared_ptr传递给lambda保持所有权。它在实际调用asio函数之前崩溃,在shared_from_this()。
上调用堆栈如下所示:
server.exe!WebsocketClient::start()
server.exe!Server::acceptConnection::__l2::<lambda>(boost::system::error_code ec)
server.exe!boost::asio::asio_handler_invoke<boost::asio::detail::binder1<void <lambda>(boost::system::error_code),boost::system::error_code> >(boost::asio::detail::binder1<void <lambda>(boost::system::error_code),boost::system::error_code> & function, ...)
server.exe!boost::asio::detail::win_iocp_socket_accept_op<boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ip::tcp,void <lambda>(boost::system::error_code) ::do_complete(boost::asio::detail::win_iocp_io_service * owner, boost::asio::detail::win_iocp_operation * base, const boost::system::error_code & result_ec, unsigned __int64 __formal) Line 142 C++
server.exe!boost::asio::detail::win_iocp_io_service::do_one(bool ec, boost::system::error_code &)
server.exe!boost::asio::detail::win_iocp_io_service::run(boost::system::error_code & ec)
server.exe!Server::run()
server.exe!main(int argc, char * * argv)
然而,当我调用shared_from_this时,我得到了bad_weak_ptr。我认为当没有shared_ptr拥有这个对象时抛出了这个,但是当我调用addPending时,我插入&#34; ptr&#34;进入一个集合,所以仍然应该有一个参考。
有什么想法吗?如果您需要更多详细信息,请询问,我会提供。这是我在StackOverflow上的第一篇文章,请让我知道我可以改进的内容。
答案 0 :(得分:1)
你可能正在处理内存损坏问题。无论是否是这种情况,您都应该采取一些故障排除步骤:
make_shared
返回的指针值,并在调用shared_from_this
之前再次在成员函数内部。检查运行对象表中是否存在该指针值(实际上是set<shared_ptr<...>>
是什么)shared_ptr
计数确实达到零,它将调用您的析构函数,调用堆栈将为您提供有关该问题的信息。如果这没有帮助,那么您使用make_shared
的事实应该是有用的,因为它可以保证元数据块就在对象旁边。
memcpy
在不同时间转储对象前面的原始字节,并注意潜在的损坏。大部分日志记录都会在显示未定义行为的上下文中发生。如果编译器发现你正在测试一些不可能的东西,它实际上可能会删除测试。在这种情况下,您通常可以通过精确使用#pragma
来管理测试,以便仅在调试日志代码上禁用优化 - 您不希望更改其余代码的优化设置,因为这可能会改变腐败的表现方式,而不会实际修复它。
答案 1 :(得分:1)
如果没有代码,很难确定问题的原因。
但是你用enable_shared_from_this
哪个,提升还是标准?
我看到你使用std::make_shared
,所以如果WebsocketClient继承boost::enable_shared_from_this
,它可能会导致崩溃。