[英]Iterating over map and erasing element
我有一個全局變量作為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)
據我了解,當我們引用不存在的內存位置時會發生這種異常。 但是我知道它存在,因為迭代器獲得了它的值並被打印出來了。 即便如此,我還是使用第二種方法,以防萬一我不引用不存在的內存位置,但仍然遇到異常。
那么,如何遍歷打印結果然后擦除的元素呢?
更新1
按照下面的建議和鏈接的主題,我將功能更改為:
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
問題仍然沒有解決,我遇到了同樣的錯誤
更新2
我在另一台機器上運行相同的代碼,但效果很好。 我仍然不知道是什么原因,所以我會像第一個std::map
的注釋中所建議的那樣進行猜測。
PS第一台機器是Mac,第二台機器是Linux
當您從映射中擦除元素時,您使循環中使用的迭代器無效,從而導致錯誤。 由於這個原因,擦除方法返回一個迭代器。
for( auto it = MyMap.begin(); it != MyMap.end(); )
{
std::cout << it->second;
it = MyMap.erase(it);
}
這確實是一個重復的問題。 您只是不太了解它,以致發現它是重復的。 我希望有關使迭代器無效的解釋有助於清除它。
在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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.