使用std:unordered_map的踩坑記

2021-01-07 馬鳴風蕭蕭蕭

C++程式設計師基本上每段程序都要和stl打交道,其中std::unordered_map是最常用的數據結構之一。接下來就介紹一個我使用unordered_map的時候遇到的一個坑。

很多程式設計師都會說,unordered_map使用很簡單呀,有什麼可講的。那我問一個簡單的問題:如何判斷一個元素在不在unordered_map裡面?

如果是寫慣了PHP的同學,上來就會用[]直接訪問,訪問不到就判斷是不是NULL就好了。就像下面的程序:

執行結果為:

看起來沒有任何問題。

但是如果我們多線程的訪問會發生什麼呢?

這段程序執行會發生什麼呢?

我們發現會有讀不到的情況

為什麼會這樣呢?

我們看下unorder_map的源碼

這是典型的 hash 操作的寫法

先對 key 算出 hash code找到這個 hash code 對應的桶在這個桶裡面,遍歷去找這個 key 對應的節點把節點返回但是如果找不到節點,不是返回空,而是會創建一個新的空白節點,然後返回這個空白節點。

這裡本質上是一個insert操作,所以在多線程讀unordered_map的時候,需要注意如果有判斷元素是否存在的場景,避免使用[]。

應該怎麼辦呢?

很簡單,使用find操作就可以啦。大家可以自己嘗試下。

相關焦點

  • go語言底層數據結構之map解析
    如果go語言是傳遞引用的話,那輸出應該是false,但是實際輸出是true,fn內部申請的map[int][int]不影響外部m,那此時我們就要問:如果map不是引用類型,那map是什麼?可以看到m是一個struct hash<int, int>結構,這種形式就像c++中的模板,因為此處m聲明的是map[int][int],所以實例化struct hash<K,T>的時候就是key類型int,value類型int(註:此處只是以c++中模板為例子,實際go沒有使用模板實現)
  • Proe/Creo使用常見問題-如何清理std.out和trail.txt文件
    今天我們一起來學習一下,如何設置Proe/Creo軟體的起始位置,如果你使用過Proe或者Creo軟體的話就一定遇到過電腦出現一堆的std.out和trail.txt垃圾文件,你每次啟動Proe或者Creo軟體都會產生一個std.out和trail.txt垃圾文件,這個文件對我們不僅沒有任何作用反而佔用電腦內存資源
  • python-stdnum 0.9 發布
    python-stdnum 0.9 發布,此版本包括了一些新的數值格式(Brin number, Postcode, ATIN, EIN, ITIN, PTIN 和 TIN);對更新 stdnum
  • MapStruct的使用,java實體類的轉換
    準備工作:Maven配置,需要我們在pom文件中添加以下引用<properties><org.mapstruct.version>1.2.0.Final</org.mapstruct.version></properties><dependency><groupId>org.mapstruct
  • Python入門基礎之map()、reduce()函數使用
    1、 map()函數map()是 python 內置的高階函數,它接收一個函數 f 和一個 list,並通過把函數 f 依次作用在 list 的每個元素上,得到一個新的object並返回。(python2返回列表,Python3返回迭代對象)map()的使用方法形如map(f(x),Itera),它有兩個參數,第一個參數為某個函數,第二個為可迭代對象。
  • JAVA map的用法/如何遍歷MAP
    下面介紹下它的使用方法。第一步,,要引入它所在JAR—— 可以在JAVA類裡直接引入import java.util.*;  這樣until下的所有接口都可以調用,還有常用到的是List.第二步: Map map=new HashMap();  //接著向MAP中添加數據進入,如下所示         map.put("a",     "1");            map.put("b",     "2");            map.put("c",     "3");   第三步:上面我們已經在MAP中添加了三條數據進去,我們可以用下面這句取值
  • 從頭使用.map() .filter() 和.reduce(),你會有意想不到的收穫!
    在「碼農圈」,學習如何使用.map()、.filter()和.reduce()函數,我們讀到、看到和聽到的一切都很複雜,無法理解這些概念,因為它們是獨立的學習單元。聽說這些是意味著上升至啟蒙狀態的入門知識。
  • Java之Map集合的第二種遍歷方式,使用Entry對象遍歷
    使用Entry對象中的方法getKey()和getValue()獲取key和value。=new HashMap<>(); map.put(01,"小明"); map.put(02,"小紅"); map.put(03,"李華");//1.遍歷Map集合中的方法entrySet(),把Map集合中多個Entry對象取出來
  • 在Python中使用Pandas
    在這篇文章中,我們將討論如何使用Pandas庫進行數據選擇、聚合和統計分析。我們開始吧!我們將使用銀行客戶流失建模數據集。數據可以在這裡找到。例如,如果我們想計算信用評分的平均值和標準差,可以執行以下操作:mean_credit_score = df['CreditScore'].mean()print('Mean credit Score: ', mean_credit_score)std_credit_score = df['CreditScore'].std()print('Standard Deviation in
  • 計算機中的Map接口
    例子:Map<String,String> map=new HashMap<String,String>();使用put方法增加操作。map.put("B", "banana");map.put("A", "apple");map.put("C", "casey");System.out.println(map);輸出結果為:{A=apple
  • Java之Map集合的遍歷
    Map集合中第一種遍歷方式,通過key找到value,實現步驟:1.使用Map集合中的方法KeySet(),把Map中所有的Key取出來,存儲到一個set集合中。2.遍歷set集合,獲取map集合中的每一個key。
  • 使用Java8 Stream API對Map類型按照鍵或值進行排序
    一、什麼是Java 8 Stream使用Java 8 Streams,我們可以按鍵和按值對映射進行排序。如果對Comparator不熟悉,可以看本號前幾天的文章,有一篇文章專門介紹了使用Comparator對List進行排序。
  • java基礎入門-day19-Map子類
    =,string>new Hashtable();,>map.put("name", "zhangSan");map.put("sex", "male");map.put("age", "22");//
  • 一文弄懂apply、map和applymap三種函數的區別
    ,希望這一篇文章能夠幫助有需要的小夥伴弄懂他們之間的區別,並且在遇到問題的時候能夠很清楚明白用哪個以及該怎樣使用。這個運算,map也可以實現。map首先,還是看下官方文檔是怎麼說的:· 根據輸入對應關係映射Series的值。
  • Java之Map接口的常用方法
    返回值:v存儲key和value的時候,key不重複,返回值v是null存儲key和value的時候,key重複,會使用新的value代替map中重複的value,返回被替代的value值代碼如下:public class Demo09Map
  • python高階函數:map、filter、reduce的替代品
    高階函數是一種將函數作為參數,或者把函數作為結果返回的函數,map函數、sorted函數就是高階函數的典型例子。map函數在小編以前的文章中做過相應的知識分享。sorted函數是python的內置函數,它的可選參數key用於提供一個函數,它可以將函數應用到各個元素上進行排序。根據單詞長度,使用sorted函數對一個列表進行排序。