c++ STL容器在迴圈中刪除迭代器的處理細節
阿新 • • 發佈:2018-12-23
c++中STL容器vector/list/map/set/deque/string等刪除元素的問題,迭代器容易出現以下錯誤,示例程式碼如下:
根本原因是:當容器中的一個元素被刪除時,指向該元素後續的迭代器變得無效。上面的程式碼中,只要執行了erase(it),那麼it就會變得無效,那麼執行it++就肯定會出錯。
通常有兩條規則:
1. 對於節點式容器(map, list, set)元素的刪除,插入操作會導致指向該元素的迭代器失效,其他元素迭代器不受影響
2. 對於順序式容器(vector,string,deque)元素的刪除、插入操作會導致指向該元素以及後面的元素的迭代器失效
供參考的正確的寫法如下:
1.對於節點式容器(map/list/set)
std::vector<int> arrayList;
...
std::vector<int>::iterator it = arrayList.begin();
for ( ; it != arrayList.end(); it++)
{
if (...)
arrayList.erase(it);
}
顯然若條件為真即if(...)為true,那麼程式執行除錯就會崩潰。
根本原因是:當容器中的一個元素被刪除時,指向該元素後續的迭代器變得無效。上面的程式碼中,只要執行了erase(it),那麼it就會變得無效,那麼執行it++就肯定會出錯。
通常有兩條規則:
1. 對於節點式容器(map, list, set)元素的刪除,插入操作會導致指向該元素的迭代器失效,其他元素迭代器不受影響
2. 對於順序式容器(vector,string,deque)元素的刪除、插入操作會導致指向該元素以及後面的元素的迭代器失效
供參考的正確的寫法如下:
1.對於節點式容器(map/list/set)
2.對於順序式容器(vector/string/deque)std::map<int, struct> mapInfo; ... std::map<int, struct>::iterator it = mapInfo.begin(); while (it != mapInfo.end()) { if (...) { // 刪除節點的前,對迭代器進行後移的操作,因為其他元素不會失效 mapInfo.erase(it++); } else { it++; } }
補充說明:容器看具體STL庫的實現了, VS中兩類容器的earse都返回下一個迭代器指標。std::vector<int> arrayInt; ... std::vector<int>::iterator it = arrayInt.begin(); while (it != arrayInt.end()) { if (...) { // 需要注意的是,因為順序式容器會使本身和後面的元素迭代器都失效,所以不能簡單的++操作 // 順序式容器的erase()會返回緊隨被刪除元素的下一個元素的有效迭代器(節點式容器的erase()的返回值是void) it = arrayInt.erase(it); } else { it++; } }