我有一个全局变量map
和一个遍历此map
元素的函数,例如:
void printMap(){
for ( auto it = MyMap.begin(); it != MyMap.end(); ++it ){
std::cout << it->second;
}
}
工作正常。
我想在打印元素后为函数添加一个功能,它应该从map
中删除,如下所示:
void printMap(){
for ( auto it = MyMap.begin(); it != MyMap.end(); ++it ){
std::cout << it->second;
MyMap.erase(it);
}
}
然而,通过添加擦除行,我得到了这种类型的异常错误:
线程2:EXC_BAD_ACCESS(代码= 1,地址= 0x20000002)
我尝试了另一种方式:
void myFunction(){
printMap();
MyMap.clear();
}
但我也得到了同样的例外
线程2:EXC_BAD_ACCESS(代码= 1,地址= 0x0)
据我所知,当我们引用不存在的内存位置时会发生这种异常。但是我知道它存在,因为迭代器得到了它的价值而且它被打印了。即便如此,我还是使用了第二种方法,以防我没有提到不存在的内存位置,但我仍然得到了异常。
那么如何迭代元素打印结果然后擦除呢?
UPDATE1
按照以下建议和链接主题,我将我的功能改为:
void printMap(){
bool i = true;
for (auto it = MyMap.cbegin(), next_it = MyMap.cbegin(); it != MyMap.cend(); it = next_it)
{
cout << it->second;
next_it = it; ++next_it;
if (i) {
MyMap.erase(it);
}
}
}
我也试过这个https://stackoverflow.com/a/42820005/7631183和https://stackoverflow.com/a/42819986/7631183
问题仍然是不已解决,而且我收到同样的错误
的 UPDATE2
我在不同的机器上运行相同的确切代码,它工作正常。我仍然不知道是什么原因,所以我会按照std::map
对第一个问题的评论中的建议进行猜测。
P.S。第一台机器是mac,第二台机器是Linux
答案 0 :(得分:2)
当您从地图中删除元素时,您已使循环中使用的迭代器无效,从而导致错误。由于这个原因,erase方法返回一个迭代器。
for( auto it = MyMap.begin(); it != MyMap.end(); )
{
std::cout << it->second;
it = MyMap.erase(it);
}
这确实是一个重复的问题。你只是不太了解它,看它是重复的。我希望解决迭代器无效的解释有助于清除它。
答案 1 :(得分:0)
在C ++ 11及更高版本中,std:map::erase()
会向正在删除的元素后面的元素返回iterator
。由于您使用的是auto
,因此您使用的是C ++ 11或更高版本,因此在循环浏览std::map
时可以使用新的迭代器,例如:
void printMap(){
auto it = MyMap.cbegin();
while (it != MyMap.cend()) {
std::cout << it->second;
it = MyMap.erase(it);
}
}
此外,由于您使用的是C ++ 11,因此可以使用range-for
循环简化您的第一个打印功能:
void printMap(){
for ( auto &it: MyMap ){
std::cout << it.second;
}
}