迭代器的有效性

在STL中,對於容器vector,deque,如果執行了插入或者刪除操作之後,之前的迭代器都失效了。
用例子來說明情況。
我們先構造一個vector:

    vector<int> v;
    int i = 0;

    for (i=1;i<6;i++)
    {
        v.push_back(i);
    }
    for (i=5;i>0;i--)
    {
        v.push_back(i);
    }

    cout<<"Initial contents of v: \n";
    for (i=0;i<v.size();i++)
    {
        cout<<v[i]<<" ";
    }
    cout<<"\n\n";

這裏寫圖片描述
這時要求刪除vector中的元素值爲4的那兩個元素

    //定義一個迭代器,指向值爲4的元素
    vector<int>::iterator iter = v.begin() + 3;
    cout<<"value of iter: "<<*iter<<"\n";
    for (i = 0;i<v.size();i++)
    {
        if (*iter == v[i])
        {
            v.erase(iter);//vector iterator not dereferencable
        }
    }

當i=3時,遇到了第一個值爲4的元素,此時調用了erase函數來刪除此元素,正常執行;i=4時,執行*iter == v[i]時,就會報錯,錯誤說明就是:vector iterator not dereferencable,這表明之前定義的iter迭代器失效了,再使用iter就會遇到這個問題,原因就是erase刪除元素後,導致的iter迭代器失效。
所以當迭代器失效後,就要重新給迭代器賦值。
例如,修改之前代碼中的內容:

    //定義一個迭代器,指向值爲4的元素
    vector<int>::iterator iter = v.begin() + 3;
    cout<<"value of iter: "<<*iter<<"\n";
    for (i = 0;i<v.size();i++)
    {
        if (*iter == v[i])
        {
            int n = v[i];
            v.erase(iter);
            //查找vector中值爲4的元素,返回迭代器指向此元素
            iter = find(v.begin(),v.end(),n);
            if (iter == v.end())
            {
                break;
            }
        }
    }

這裏我們以下語句實現通過重新查找vector內是否還有值爲4的元素,如果有就返回指向此元素的迭代器,如果沒有就返回end(),重新給iter賦新的迭代器

iter = find(v.begin(),v.end(),n);

最後在輸出vector內容:

    cout<<"after erase(), contents of v: \n";
    for (i=0;i<v.size();i++)
    {
        cout<<v[i]<<" ";
    }
    cout<<"\n\n";

如預期一樣刪掉了vector中的值爲4的元素,而且也沒有迭代器失效的問題。
這裏寫圖片描述

總結:在使用迭代器時,要特別注意當刪除或者插入操作之後,迭代器的有效性問題,STL中沒有對於迭代器有效性的檢查功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章