1. 程式人生 > >vector和map的迭代器失效問題

vector和map的迭代器失效問題

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兩種方式都可以正常工作

STL的容器刪除元素,除了使用迭代器外,還可以使用erase(key)的方式。 size_t rm_num = obj.erase(key); rm_num標示刪除key的成員的個數,在map中key是key值,在其他容器中,key是一個value。