c++ - Boost strand post 在访问/插入值时导致段错误

标签 c++ c++11 post boost asio

我目前正在编写一个网络结构,它只让服务器监听它自己的链,很简单。每当调用链来调用函数并且该函数调用类中的任何成员时,就会发生段错误。

有一些异常(exception),但值得注意的是这些段错误发生在

  1. tcp::acceptor myAcceptor(my_io_service, myEndpoint)
  2. mySockets.insert(...)

现在我可以轻松交换 myAcceptor 并将其放在构造函数的初始化列表中,并将其视为类成员,但我想避免这种情况。

那么接下来要验证我的主张是什么?我最近的尝试是检查 mySockets 的大小,我应该注意,它是一个映射。我在调用 myStrand.post(...) 之前检查了大小,并在函数调用中检查了大小。这是我注意到的。

mySockets 映射大小:

  1. 发布前:0(未插入任何内容,太棒了!)
  2. 在函数调用中,通过 post 调用:999929272 (Ughhhh)

似乎有些东西变了味,但究竟是什么?它是否创建了一个新实例,但奇怪的是这不是 0 吗?它不可能丢失地址,因为这肯定会导致段错误,不是吗?

这就是我目前在调试过程中所处的位置。

目标

最终目标是能够在 post strand 中访问 mySockets 和 my_io_service。

布局流程

这解释了布局,好的代码在下面

  1. 通过传递 io_service 创建“工作”
  2. 通过调用 .run() 启动 io_service
  3. 创建 TCP 服务器
  4. 为类成员类型分配参数
  5. 调用 myStrand.post(...) 来调用服务器,监听连接的客户端
  6. 等待客户端连接等

我选择了详细说明问题的代码示例。

头文件

using boost::asio::ip::tcp;
bool amIConnected = false;
boost::asio::io_service::strand myStrand;
boost::asio::io_service& my_io_service;
std::map<std::string, std::shared_ptr<tcp::socket>> mySockets;
tcp::acceptor myAcceptor

源文件

ConstructorStuff::ConstructorStuff(boost::asio::io_service& the_service) : 
myStrand(the_service), 
my_io_service(the_service),
myAcceptor(the_service, tcp::endpoint(tcp::v4(), 1337))
{}

void ConstructorStuff::CreateTheServer()
{
    amIConnected = true;
    // std::cout << mySockets.size() << std::endl; Returns 0
    mStrand.post(std::bind(&ConstructorStuff::ListenForConnection, this));
}

void ConstructorStuff::ListenForConection()
{
    // std::cout << mySockets.size() << std::endl; Crazy size
    tcp::acceptor tryAgain(my_io_service, tcp::endpoint(tcp::v4(), 1338)); // Just to showcase the error doesn't just occur through mySockets.
}

调用ConstructorStuff的地方

void SetupServer()
{
    ConstructorStuff stuff(some_service);
    stuff.CreateTheServer();
}

这会调用上面的函数

ServiceStarter spinup(service);
spinup.Start(); // Just queues reference_service.run()
std::shared_ptr<SomeClass> server_interface(new SomeClass ( service ));
server_interface->SetupServer();
boost::this_thread::sleep(boost::posix_time::seconds(20));
server_interface->Cancel(); // Just another function that kills the server.

任何建议都会很棒!

旁注:

  • 任何额外的值,例如放在头文件中的 myPort,在 CreateTheServer() 中初始化为 1337,然后在 ListenForConnection() 中调用会突然不同。
  • 为了让任何可能会问的人放心,这些值可以在链的外部访问,从而将此问题锁定为我遇到的与链相关的问题。

编辑

我添加了两个新的源文件。我能展示的内容非常有限,但这应该足以说明问题。

最佳答案

问题出自SetupServer其中 stuff是局部变量,所以在 CreateTheServer 之后被称为,stuffio_service::run 摧毁并在某处mStrand.post(std::bind(&ConstructorStuff::ListenForConnection, this)); 发布的处理程序被删除的对象调用。那么std::cout << mySockets.size() << std::endl;打印出奇怪的结果 - 这是一个未定义行为的简单示例。

关于c++ - Boost strand post 在访问/插入值时导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56673167/

相关文章:

c++ - 不调用赋值运算符

c++ - 如何在不闪烁的情况下以自定义大小启动控制台?

c++ - 添加到动态库中的函数指针映射

c++ - 动态库中的 libstdc++ 静态链接

c++ - C++14/17 项目是否可以使用使用 C++11 标准编译的二进制库,或者源代码是否需要重新编译?

jquery - 使用 jquery POST 请求后重定向

php - jquery 发布和响应操作

c++ - 在 CPP 中初始化一个 2 Dimensional vector<int>

html - 为什么 AJAX 而不是 iFrame?

c++ - 令人惊讶的是, vector <char> 的自定义分配器效率低下