C++ - unordered_map 运算符 [],意外行为
Posted
技术标签:
【中文标题】C++ - unordered_map 运算符 [],意外行为【英文标题】:C++ - unordered_map operator [], unexpected behavior 【发布时间】:2020-04-01 00:27:39 【问题描述】:这是我正在编写的一个简单脚本,但我不明白为什么它的行为异常。
基本上,我有一个带有重复的整数数组,我想将元素在数组中出现的次数连同元素的值一起存储在 unordered_map 中,
然后,对于映射 k, v 中的每个条目,我需要确定数组中是否存在 k + 1 ,如果是这样,用它做点什么。 下面你可以看到代码。
vector<int> A = 1, 1, 3, 2, 5, 3;
for (int i = 0; i < A.size(); ++i) m[A[i]]++;
int ans = 0;
for (const auto& e: m)
if (m[e.first + 1] > 0) ans = max(ans, e.second + m[e.first + 1]);
似乎一切正常。但是,当 k + 1 在 unordered_map 中不存在时,循环就会终止,我不明白为什么。
根据 c++ 文档,运算符 [] 插入一个新元素,如果它不存在。但这并没有告诉我任何关于循环不起作用的信息。
我怀疑这与我在循环中修改 unordered_map 的事实有关。如果是这样的话,你们能详细说明一下吗?
非常感谢您的帮助。
【问题讨论】:
【参考方案1】:在循环中使用m[e.first + 1]
将在m
中插入一个新元素(如果它不存在),这将导致循环本身出现问题,因为range-based for
loop 在内部使用迭代器,并在您更改std::unordered_map
时使用迭代器进行迭代是未定义的行为,如an insertion may invalidate the iterators:
如果发生插入并导致容器重新散列,则所有迭代器都将失效。否则迭代器不受影响。引用不会失效。仅当新元素数大于
max_load_factor()*bucket_count()
时才会进行重新散列。
为避免这种情况,请改用映射的 find()
方法来检查键是否存在而不插入它:
for (const auto& e: m)
auto iter = m.find(e.first + 1);
if (iter != m.end()) ans = max(ans, e.second + iter->second);
【讨论】:
以上是关于C++ - unordered_map 运算符 [],意外行为的主要内容,如果未能解决你的问题,请参考以下文章