当访问/插入值时,增强链发布导致分段错误

时间:2019-06-19 17:37:41

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

我目前正在编写一种网络结构,该结构仅使服务器能够监听其自身的链,非常简单。每当调用该链来调用一个函数并且该函数从类中调用任何成员时,就会发生分段错误。

有一些例外,但值得注意的是,这些分段错误发生在

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

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

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

mySockets映射大小:

  1. 发布前:0(没插入任何内容,太好了!)
  2. 在函数内调用,通过帖子调用:999929272(Ughhhh)

似乎有些通风不良,但究竟是什么?它是否创建了新实例,但是奇怪的是它不是0吗?它不能丢失地址,因为这肯定会导致分段错误,不是吗?

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

目标

最终目标是能够在发布链中访问mySockets和my_io_service。

布局流程

这说明了布局,好的ol代码在下面

  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()中调用会突然不同。
  • 为了使任何人都可以放心,可以在链中 OUTSIDE 之外访问这些值,从而将此问题锁定为我遇到的与链相关的问题。

修改

我添加了两个新的源文件。我只限于可以显示的内容,但这足以说明问题。

1 个答案:

答案 0 :(得分:1)

问题来自SetupServer,其中stuff是局部变量,因此在调用CreateTheServer之后,stuff被销毁,并由io_service::run处理程序发布在已删除的对象上调用了mStrand.post(std::bind(&ConstructorStuff::ListenForConnection, this));。然后std::cout << mySockets.size() << std::endl;打印出奇怪的结果-这是未定义行为的简单示例。