C++ - unordered_map 运算符 [],意外行为

C++ - unordered_map operator [], unexpected behavior

这是我正在处理的一个简单脚本,但我不明白为什么它会出现意外行为。

基本上,我有一个包含重复项的整数数组,我想将元素在数组中出现的次数与元素的值一起存储在 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有关。如果是这样的话,你们能详细说说吗?

非常感谢您的帮助。

如果 m 不存在,在循环中使用 m[e.first + 1] 会将一个新元素插入到 m 中,这会导致循环本身出现问题,因为 range-based for loop uses iterators internally, and altering a std::unordered_map while you are iterating through it with iterators is undefined behavior, as an insertion may invalidate the iterators:

If an insertion occurs and results in a rehashing of the container, all iterators are invalidated. Otherwise iterators are not affected. References are not invalidated. Rehashing occurs only if the new number of elements is greater than 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);
}