首页 > 解决方案 > 为什么这段代码可以在一个平台上运行,但不能在另一个平台上运行?

问题描述

我在 Windows 上编写了一个又长又复杂的服务器程序。使用视觉工作室 2019。

然后我在 vm virtualbox 上创建了一个 CentOS 8 操作系统并将所有代码转移到那里。并用可视代码重建了一个可执行文件。除了一部分之外,这可以正常工作。

以下是导致崩溃的代码:

//clients is    std::map<int, boost::shared_ptr<Client>> clients;

        for (const auto& kv : clients) {
            
            int elapsed_seconds = boost::chrono::duration_cast<boost::chrono::seconds>(timeNow - kv.second->lastUpdated).count();

            int i = kv.first;

            if (elapsed_seconds >= ServerData::SessionTimeoutSeconds)
            {
                trash_bin.push_back(clients[i]);
                clients.erase(i);
            }
        }

这在 Windows 上没有任何错误(使用 Visual Studio 2019 编译)

但是在centos 8上给出了这个错误(用可视代码/ g++编译)

断言 'px != 0' 失败。中止(核心转储)

但是如果我放了break;在 client.erase(i) 之后;问题解决了。

if (elapsed_seconds >= ServerData::SessionTimeoutSeconds)
{
    trash_bin.push_back(clients[i]);
    clients.erase(i);
    break;//this line makes it work.
}

因此,当从客户端删除某些内容后 for 循环迭代时会引起问题。

问题是 :

为什么它自动解决了这个问题,没有打破在windows上编译的代码的循环,但不能在centos 8上解决?

标签: c++visual-studio-codeboostvisual-studio-2019centos8

解决方案


for (const auto& kv : clients) {

这使用迭代器迭代范围。每次循环体执行完后,迭代器就递增。

int i = kv.first;
clients.erase(i);

这使当前迭代器无效。当无效迭代器在循环体之后递增时,程序的行为是未定义的。


 break;//this line makes it work.

为什么它能解决这个问题

因为当您在无效迭代器递增之前跳出循环时,没有未定义的行为。


推荐阅读