Asio完成处理程序中的实例变量无效
Invalid instance variable in Asio completion handler
我已经使用Asio(非boost)设置了一个简单的异步tcp服务器,它基本上遵循这里使用的代码:http://think-async.com/Asio/asio-1.11.0/doc/asio/tutorial/tutdaytime3.html
我遇到一个问题,试图访问async_read_some/async_receive的完成处理程序中当前tcp_connection实例的变量时会引发错误。有问题的变量只是指向我创建的加密类实例的指针。一旦调用完处理程序,这个指针似乎就无效了(0xFEEEFEEE的地址)。以下是tcp_connection类,该类在与客户端建立连接后创建:
class tcp_connection
: public enable_shared_from_this<tcp_connection> {
public:
typedef shared_ptr<tcp_connection> pointer;
static pointer create(asio::io_service &ios) {
return pointer(new tcp_connection(ios));
}
tcp::socket &socket() {
return socket_;
}
void start() {
byte* buf = new byte[4096];
socket_.async_receive(asio::buffer(buf, 4096), 0,
bind(&tcp_connection::handle_receive, this,
buf,
std::placeholders::_1, std::placeholders::_2));
}
private:
tcp_connection(asio::io_service &ios)
: socket_(ios) {
crypt_ = new crypt();
}
void handle_receive(byte* data, const asio::error_code &err, size_t len) {
cout << "Received packet of length: " << len << endl;
crypt_->decrypt(data, 0, len); // This line causes a crash, as the crypt_ pointer is invalid.
for (int i = 0; i < len; ++i)
cout << hex << setfill('0') << setw(2) << (int)data[i] << ", ";
cout << endl;
}
tcp::socket socket_;
crypt* crypt_;
};
我认为这与Asio在内部使用线程的方式有关。不过,我本以为会使用当前tcp_connection实例调用完成处理程序(handle_receive)。
我缺了什么吗?我对阿西奥不太熟悉。提前谢谢。
首先,当只有现存的异步操作时,应该使用shared_from_this
来防止tcp_connection
被"收集":
socket_.async_receive(asio::buffer(buf, 4096), 0,
bind(&tcp_connection::handle_receive, shared_from_this()/*HERE!!*/,
buf,
std::placeholders::_1, std::placeholders::_2));
其次,tcp_connection
类应该实现Rule Of Three(至少清除析构函数中的crypt_
并禁止复制/赋值)。
您在当前样本中也没有释放buf
。
当然,一般来说,只需对所有这些使用智能指针即可。
在Coliru上直播
相关文章:
- 返回 C++ 中的指针实例变量
- 返回实例变量的c++方法可以访问变量中的数据,但不能更改它,但在编译时不会生成错误
- C++ 实例变量初始值设定项中的重复类型
- 为什么可以在没有实例变量的情况下访问静态回调方法中的静态成员变量?
- C++ 中实例变量的双冒号
- 我可以在没有任何实例变量的情况下使用 decltype 吗?
- OpenMP 私有类实例变量
- C 取消实例变量指针
- 在C++私有区域中初始化实例变量
- 如何将指针存储在实例变量中,该指针被声明为指向基类的指针
- 如何在Arduino中创建另一个类库的实例变量
- 单元测试呼叫实例变量的函数
- 为构造函数初始化引用实例变量提供默认值
- 如何使编译器在实例变量未初始化时C++生成错误或警告
- 如何超载分配运算符,该操作员总计两个实例变量
- C++:通过引用传递或使用私有实例变量
- 对象作为类内的实例变量
- 在不构造实例变量的情况下C++声明实例变量的好方法是什么?
- 实例变量列表中的对象未被保留?指针问题
- Asio完成处理程序中的实例变量无效