[英]While Searching for a key in a map in C++ STL, gives the following error
[英]Erasing while traversing in C++ stl map giving runtime error
以下 C++ 代碼行給出運行時錯誤,但如果刪除操作mymap.erase(v)
則它可以工作:
map<int,int> mymap = {{1,0},{2,1},{9,2},{10,3},{11,4}};
for(auto it=mymap.rbegin();it!=mymap.rend();){
int v=it->first;
++it;
mymap.erase(v);
}
這里的迭代器在刪除it
的值v
之前被改變了,所以我相信迭代器it
應該保持不受影響。
當您調用erase(v)
時,您正在使下一個reverse_iterator
(來自++it
)正在使用的基本iterator
無效。 因此,您需要從擦除值之前的基本iterator
創建一個新的reverse_iterator
。
此外,與其刪除reverse_iterator
所指的值,不如刪除基本iterator
,因為您已經知道要刪除哪個元素。 無需再次使map
go 尋找該值。
這對我有用:
map<int,int> mymap = {{1,0},{2,1},{9,2},{10,3},{11,4}};
for(auto it = mymap.rbegin(); it != mymap.rend(); ){
auto v = --(it.base());
v = mymap.erase(v);
it = map<int,int>::reverse_iterator(v);
}
另一方面,這個循環本質上只是從mymap
中erase()
所有元素,因此更好的選擇是使用mymap.clear()
代替。
事實上, std::map::erase
:
對已擦除元素的引用和迭代器無效。 其他引用和迭代器不受影響。
對於從迭代器 i 構造的反向迭代器 r,關系
&*r == &*(i-1)
始終為真(只要 r 是可取消引用的); 因此,從一個過去的迭代器構造的反向迭代器取消對序列中最后一個元素的引用。
當您查看 cppreference 頁面上的圖像時,可能會更清楚。
關鍵部分是“反向迭代器將迭代器存儲到下一個元素而不是它實際引用的元素”。
結果(對您的代碼的小修改)
auto& element = *it; // fails in the next iteration, because...
int v = element.first;
++it; // now it stores an iterator to element
mymap.erase(v); // iterators to element are invalidated
您正在擦除it
在下一次迭代中使用的元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.