当前位置: 首页 > news >正文

【C++】unordered_map在Windows和Linux上的不同行为

我目前手头上的项目,需要编译在板端Linux上运行,但是日常daily调试多在Windows上开发。这就涉及到同一份代码在多平台上的编译个运行。有一次遇到了一个奇怪的现象:跑同样的一份代码,Windows和Linux出来的结果是不一致的。最终确定到不一致的原因出现在unordered_map上,就把这次记录总结下来。

这次不一致发生在:处理一个状态序列的投票操作。从编程的角度而言,最适合投票操作的容器就是键值对,key放置投票的内容,value放置投票的次数。在C++中,STL提供了两个相关容器:map和unordered_map。在代码上选择了unordered_map来实现。


问题复现

我把这个问题简化:假设车的类型有四种情况,分别为UNKNOWN、SMALL、MIDDLE、BIG。现有15次的估计,以出现次数最多的类型作为其最终类型。代码非常简单:

#include <iostream>
#include <unordered_map>
#include <string>int main()
{std::unordered_map<std::string, int> vehs;vehs["UNKNOWN"] = 5;vehs["SMALL"] = 3;vehs["MIDDLE"] = 5;vehs["BIG"] = 2;std::string max_type;int max_times = -1;auto iter = vehs.begin();for (; iter != vehs.end(); ++iter) {if (iter->second > max_times) {max_times = iter->second;max_type = iter->first;}std::cout << iter->first << " ";}std::cout << std::endl;std::cout << "max_type : " << max_type << std::endl;return 0;
}

在Windows平台下,编译并运行代码:

BIG UNKNOWN SMALL MIDDLE
max_type : UNKNOWN

在Linux平台下,编译并运行代码:

BIG MIDDLE SMALL UNKNOWN
max_type : MIDDLE

可以看到,在Windows和Linux两个平台下的运行结果中,出现次数最多的车的类型,一个为UNKNOWN,一个为MIDDLE。主要原因是这两种类型都是5次(最多)。这时,unordered_map的遍历顺序就很重要了,这将直接关系到最终的输出结果。通过打印结果可以看到,两个平台下的遍历顺序是不一致的。

在C++中,STL提供了两个键值对容器:map和unordered_map。上面的代码,采用的是unordered_map容器,如果将其改成map容器呢?还会发生这种不一致的结果么?

std::map<std::string, int> vehs;    // 将unordered_map修改为map

此时再在Windows和Linux平台下,分别编译并运行代码,最终的输出都是一致的:

BIG MIDDLE SMALL UNKNOWN
max_type : MIDDLE

也就是说,这种平台不一致性只发生在unordered_map容器上,而不发生在map容器上


原因分析

map和unordered_map分别在Windows和Linux上的不同运行结果,主要体现在遍历顺序上。对于map而言,两个平台上的遍历顺序是一致的;而对于unordered_map而言,两个平台上的遍历顺序是不一致的。

遍历顺序的不同,究其根本,主要体现在其内部构造的不同

map的内部构造:

  • map的内部实现了一个红黑树(红黑树是非严格平衡二叉搜索树,而AVL是严格平衡二叉搜索树),红黑树具有自动排序的功能,因此map内部的所有元素都是有序的。红黑树的每一个节点都代表着map的一个元素。因此,对于map进行的查找,删除,添加等一系列的操作都相当于是对红黑树进行的操作。

unordered_map的内部构造:

  • unordered_map的内部实现了一个哈希表(也叫散列表,通过把关键码值映射到Hash表中一个位置来访问记录,查找的时间复杂度可达到O(1),其在海量数据处理中有着广泛应用)。因此,其元素的排列顺序是无序的。

两者在运行效率和占用内存的对比:

  • 运行效率方面:unordered_map最高,而map效率较低,但提供了稳定效率和有序的序列
  • 占用内存方面:map内存占用略低,unordered_map内存占用略高,而且是线性成比例的

需要无序容器,快速查找删除,不担心略高的内存时可以选择unordered_map;需要有序容器稳定查找删除效率,内存很在意时候用map。

因此,如果需要使用map,那么key需要定义operator<,用于进行有序的排序;如果需要使用unordered_map,那么key需要定义hash_value函数并且定义operator==,用于hash值的计算。而:

  • 当使用map时,Windows和Linux对于operator<的定义都是一致的
  • 当使用unordered_map时,Windows和Linux对于operator==的定义都是一致的,对于hash_value函数的定义是不一致的

从而,在使用unordered_map时,Windows和Linux使用两种不同的哈希函数,产生不同的哈希码,从而依次产生不同的存储区放置,导致在迭代时产生不同的顺序


相关阅读

  • c++ - Windows 和 Linux 上 std::unordered_map 容器的不同行为

相关文章:

【C++】unordered_map在Windows和Linux上的不同行为

我目前手头上的项目&#xff0c;需要编译在板端Linux上运行&#xff0c;但是日常daily调试多在Windows上开发。这就涉及到同一份代码在多平台上的编译个运行。有一次遇到了一个奇怪的现象&#xff1a;跑同样的一份代码&#xff0c;Windows和Linux出来的结果是不一致的。最终确定…...

Apipost三方消息通知,接口变更不用愁

Apipost致力于为开发者提供更全面的API管理功能。而最近&#xff0c;Apipost又新增了一个非常实用的功能&#xff1a;第三方消息推送。这个功能可以帮助开发人员及时了解API的变更情况&#xff0c;从而更好地管理和优化自己的API。 具体来说&#xff0c;Apipost的第三方消息推…...

C语言 用数组名作函数参数

当用数组名作函数参数时&#xff0c;如果形参数组中各元素的值发生变化&#xff0c;实参数组元素的值随之变化。 1.数组元素做实参的情况&#xff1a; 如果已经定义一个函数&#xff0c;其原型为 void swap(int x,int y);假设函数的作用是将两个形参&#xff08;x,y&#xf…...

每日一题(980. 不同路径 III)-回溯

题目 980. 不同路径 III 题解思路 表格中值为1的为起始点值为0 的是可以经过的点&#xff0c;但是只能经过一次值为2 的是终点&#xff0c;计算从起点到终点一共有多少种路径 计算出值为0的方格个数&#xff0c;同时找到起点位置当位于终点时候且经过所有的方格为0的点 即为…...

【Python:json常用函数,用于加载和保存json文件】load(), loads(), dump(), dumps()

文章目录 1、load()2、loads()3、dump()4、dumps() json文件为javascript object Notation文件&#xff0c;属于轻量级的数据交换格式&#xff0c;可以用于存储和交换数据。json文件是由类似{ }的key-value映射组成。 1、load() 把json文件加载为Python的数据格式&#xff0c…...

Flink State 和 Fault Tolerance详解

有状态操作或者操作算子在处理DataStream的元素或者事件的时候需要存储计算的中间状态&#xff0c;这就使得状态在整个Flink的精细化计算中有着非常重要的地位&#xff1a; 记录数据从某一个过去时间点到当前时间的状态信息。以每分钟/小时/天汇总事件时&#xff0c;状态将保留…...

小红书2023“家生活”趋势白皮书

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 近年来&#xff0c;年轻人与家的关系愈发紧密。 在小红书上&#xff0c;我们观察到了家居家装内容的蓬勃生长&#xff0c;3 年来相关内容的笔记规模增长了6倍&#xff0c;相关品类的搜索量增加的 3.…...

使用 LangChain 搭建基于 Amazon DynamoDB 的大语言模型应用

LangChain 是一个旨在简化使用大型语言模型创建应用程序的框架。作为语言模型集成框架&#xff0c;在这个应用场景中&#xff0c;LangChain 将与 Amazon DynamoDB 紧密结合&#xff0c;构建一个完整的基于大语言模型的聊天应用。 本次活动&#xff0c;我们特意邀请了亚马逊云科…...

210. 课程表 II Python

文章目录 一、题目描述示例 1示例 2示例 3 二、代码三、解题思路 一、题目描述 现在你总共有 numCourses 门课需要选&#xff0c;记为 0 到 numCourses - 1。给你一个数组 prerequisites &#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示在选修课程 ai 前 必须 …...

【LeetCode 算法】Linked List Cycle II 环形链表 II

文章目录 Linked List Cycle II 环形链表 II问题描述&#xff1a;分析代码哈希快慢指针 Tag Linked List Cycle II 环形链表 II 问题描述&#xff1a; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链…...

蒸散发与植被总初级生产力估算

目标 熟悉蒸散发ET及其组分&#xff08;植被蒸腾Ec、土壤蒸发Es、冠层截留Ei&#xff09;、植被总初级生产力GPP的概念和碳水耦合的基本原理&#xff1b;掌握利用Python与ArcGIS工具进行课程相关的操作&#xff1b;熟练掌握国际上流行的Penman-Monteith模型&#xff0c;并能够…...

uniapp微信小程序底部弹窗自定义组件

基础弹窗效果组件 <template><view><viewclass"tui-actionsheet-class tui-actionsheet":class"[show ? tui-actionsheet-show : ]"><view class"regional-selection">底部弹窗</view></view><!-- 遮罩…...

人工智能的最新进展:2024年将会发生什么?

文章目录 2024年AI最新发展2024年AI具体应用2024年AI的具体预测 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xff1a;全栈弄潮儿的个人社区 &#x1f4d9; 专栏地址&#…...

使用Golang实现一套流程可配置,适用于广告、推荐系统的业务性框架——组合应用

在《使用Golang实现一套流程可配置&#xff0c;适用于广告、推荐系统的业务性框架——简单应用》中&#xff0c;我们看到了各种组合Handler的组件&#xff0c;如HandlerGroup和Layer。这些组件下面的子模块又是不同组件&#xff0c;比如LayerCenter的子组件是Layer。如果此时我…...

DNS入门学习:DNS缓存的原理和作用(中科三方)

在实际业务场景中&#xff0c;DNS解析过程并不总是严格遵循从根域名服务器、顶级域名服务器再到权威域名服务器的一级级查询过程&#xff0c;这只是一个标准状态。为了节省全球查询的时间&#xff0c;同时减轻各级服务器的解析压力&#xff0c;DNS系统中引入了缓存机制。本文中…...

Linux虚拟机安装tomcat(图文详解)

目录 第一章、xshell工具和xftp的使用1.1&#xff09;xshell下载与安装1.2&#xff09;xshell连接1.3&#xff09;xftp下载安装和连接 第二章、安装tomcat1.1&#xff09;关闭防火墙&#xff0c;传输tomcat压缩包到Linux虚拟机12&#xff09;启动tomcat 第一章、xshell工具和xf…...

Matlab对TMS320F28335编程--SVPWM配置互补PWM输出

前言 F28335中断 目的&#xff1a;FOC的核心算法及SVPWM输出&#xff0c;SVPWM的载波频率10kHz&#xff0c;SVPWM的每个周期都会触发ADC中断采集相电流&#xff0c;SVPWM为芯片ePWM4、5、6通道&#xff0c;配置死区 1、配置中断SVPWM进ADC中断&#xff0c;查上表知CPU1,PIE1 …...

MySQL数据库——多表操作

文章目录 前言多表关系一对一关系一对多/多对一关系多对多关系 外键约束创建外键约束插入数据删除带有外键约束的表的数据删除外键约束 多表联合查询数据准备交叉连接查询内连接查询外连接查询左外连接查询右外连接查询满外连接查询 子查询子查询关键字ALL 关键字ANY 和 SOME 关…...

Java版本spring cloud + spring boot企业电子招投标系统源代码 tbms

​ 功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为…...

css实现,正常情况下div从左到右一次排列,宽度超出时,右侧最后一个div固定住,左侧其他div滚动

需求:正常情况下 宽度超出时: 实现: <templete><div class"jieduanbox"><div v-for"(item, index) in stageList" :key"index" style"display: inline-block">.......</div><div class"rightBtn&q…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...