c++ - 为什么这段代码可以在一个平台上运行,但不能在另一个平台上运行?
问题描述
我在 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上解决?
解决方案
for (const auto& kv : clients) {
这使用迭代器迭代范围。每次循环体执行完后,迭代器就递增。
int i = kv.first; clients.erase(i);
这使当前迭代器无效。当无效迭代器在循环体之后递增时,程序的行为是未定义的。
break;//this line makes it work.
为什么它能解决这个问题
因为当您在无效迭代器递增之前跳出循环时,没有未定义的行为。
推荐阅读
- python - 如何从 DataFrame 创建一个 float64 向量,其中 DF 列的每个条目都有 n 个向量条目?
- json - 预接收挂钩,Bash + Git
- python-3.x - 跨函数更新变量
- java - 如何在没有 sudo 的情况下在 ubuntu 上将 java 的版本从 8 更改为 11
- android - Flutter 应用程序在发布模式下显示灰屏,但在调试模式下工作正常 'DiagnosticsProperty 实例
' - scikit-learn - 为什么 knimputer 给出这个输出?
- ios - AppStore:如何在单个应用容器中发布更多应用?
- facebook-opengraph - Squarespace 和 Open Graph,获取产品 ID?
- reactjs - 如何使用咖啡在 Rails 中使用 React?
- swiftui - SwiftUI - 对象显示在我的 HStack 之外