【发布时间】:2021-11-03 16:19:59
【问题描述】:
尝试使用以下代码 sn-p 更新无序映射以仅包含小写字母,但在删除一个键值对 { [33 '!']: 3 } 后它似乎停止并退出循环离开地图的其余部分未访问并打印部分更新的地图。
for (auto &i : m)
if (!(i.first >= 'a' && i.first <= 'z'))
m.erase(i.first);
以下调试图像揭示了上述情况
完整代码如下:
#include <iostream>
#include <unordered_map>
#include <algorithm>
using namespace std;
int main()
{
string line = "Try! Try! Try! until you succeed";
//getline(cin, line);
unordered_map<char, int> m;
for (int i = 0; line[i]; i++)
{
char lower = (char)tolower(line[i]);
if (m.find(lower) == m.end())
m.insert(make_pair(lower, 1));
else
m[lower]++;
}
for (auto &i : m) //only updates until !
if (!(i.first >= 'a' && i.first <= 'z'))
m.erase(i.first);
cout<<"The freq. map so formed is : \n";
for (auto &i : m)
cout<<i.first<<"\t"<<i.second<<endl;
return 0;
}
/*
OUTPUT :
The freq. map so formed is :
d 1
t 4
r 3
e 2
y 4
l 1
o 1
5
n 1
u 3
i 1
s 1
c 2
*/
似乎无法理解为什么它不会遍历完整的无序地图。
此外,不确定这是否有助于获得清晰的图片,但是,当使用标准地图而不是无序地图时,它会在需要更新地图的下一个字符的同一实例中给出地址边界错误,如下所示:
【问题讨论】:
-
在迭代容器时从容器中擦除元素...您不能用于范围,您必须回退到迭代器。
-
在迭代容器时修改容器可能会导致问题。我建议使用迭代器的“正常”
for循环,并注意theerasefunction 返回。 -
在那个范围循环中有一个“幕后”的迭代器,它被
erase无效。 -
使用
insert或erase之类的函数时,您必须阅读文档以了解该操作的无效内容(迭代器、引用...)一个给定的容器,直到你有足够的经验来了解规则......还要检查函数返回和采样的内容。
标签: c++ segmentation-fault unordered-map