vector和map的迭代器失效問題
阿新 • • 發佈:2019-01-02
1.vector
#include <iostream> #include <string> #include <vector> using namespace std; void vectorTest() { vector<int> container; for (int i = 0; i < 10; i++) { container.push_back(i); } vector<int>::iterator iter; for (iter = container.begin(); iter != container.end(); iter++)//迴圈2 { container.erase(iter); } for (iter = container.begin(); iter != container.end(); iter++) { cout<<*iter<<endl; } } int main(int argc, const char *argv[]) { vectorTest(); return 0; }
執行結果 : 0 1 2 3 5 7 9
在vector中刪除一個元素時,後面的元素會前移一位,所以原來的迭代器都失效了
刪除第一個比3大的數4後:0 1 2 3 5 6 7 8 9
--->但是此時迭代器指向5,然後iter++,又指向6了,把5漏掉。。。導致的是後面有5 7 9依然沒刪除
修改的方法:在迴圈2中:
for (iter = container.begin(); iter != container.end();) { if(*iter > 3) { container.erase(iter); continue; } iter++; }
或者:
for (iter = container.begin(); iter != container.end();)
{
if(*iter > 3)
{
iter = container.erase(iter);//此時的iter指向的位置沒有變,只是此時指向的內容變成原來元素後面的一個了
continue;
}
iter++;
}
2.map的失效
map是關聯容器,以紅黑樹或者平衡二叉樹組織資料,雖然刪除了一個元素,整棵樹也會調整,以符合紅黑樹或者二叉樹的規範,但是單個節點在記憶體中的地址沒有變化,變化的是各節點之間的指向關係
序列性容器::(vector和list和deque)
erase迭代器不僅使所指向被刪元素的迭代器失效,而且使被刪元素之後的所有迭代器失效,所以不能使用erase(iter++)的方式,但是erase的返回值為下一個有效的迭代器。
所以正確方法為::
for( iter = c.begin(); iter != c.end(); )
iter = c.erase(iter);
關聯性容器::(map和set比較常用)
erase迭代器只是被刪元素的迭代器失效,但是返回值為void,所以要採用erase(iter++)的方式刪除迭代器,
所以正確方法為::
for( iter = c.begin(); iter != c.end(); )
c.erase(iter++);
Tips:
其實對於list兩種方式都可以正常工作