刪除STL容器中的元素

有關stl容器刪除元素的問題,錯誤的代碼以下:ios

std::vector<struct> mFriendList;
...
std::vector<struct>::iterator iter = mFriendList.begin();
for ( ; iter != mFriendList.end(); ++iter)
{
    if (...)
        mFriendList.erase(iter);
}

 

記得當時Once給我說過這個問題,還給我改過代碼,我當時不明白爲何,只知道程序執行的時候若是if爲true那麼程序就確定會崩潰。
大師的說法是:當容易中的一個元素被刪除時,指向該元素的全部迭代器都變得無效。上面的代碼中,只要執行了erase(iter),那麼iter就會變得無效,那麼執行++iter就確定會出錯。

在網上看到有人總結以下兩條:
1. 對於節點式容器(map, list, set)元素的刪除,插入操做會致使指向該元素的迭代器失效,其餘元素迭代器不受影響
2. 對於順序式容器(vector,string,deque)元素的刪除、插入操做會致使指向該元素以及後面的元素的迭代器失效

總結了一下,並回想Once當時給我改的代碼,因此正確的寫法應該是這樣的:spa

1.指針

#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <iterator> 

using namespace  std;

int main(int argc, char* argv[])
{
    vector<int> MyList;
    
    for (int i = 0; i < 10; i++)
    {
        MyList.push_back(i);
    }

    vector<int>::iterator Itor = MyList.begin();

    for (;Itor != MyList.end();)
    {
        if ( *Itor == 4 )
        {
            Itor = MyList.erase(Itor);
        }
        else
        {
            Itor++;
        }
    }

    copy(MyList.begin(), MyList.end(), ostream_iterator<int>(cout, " ") );
    cout<<endl;

    return 0;
}

 


2.對於節點式容器code

//下面其它的總結, 寫法有點怪
std::list<struct> mList; ... std::list<struct>::iterator iter = mList.begin(); for ( ; iter != mList.end(); ) { if (...) { //由於節點式只會致使當前節點迭代器失效,因此刪除節點的同時對迭代器進行後移的操做,由於其餘元素不會失效 mList.erase(iter++); } else { ++iter; } }

 

3.對於順序式容器blog

std::vector<struct> mVector;
...
std::vector<struct>::iterator iter = mVector.begin();
for ( ; iter != mVector.end(); )
{
    if (...)
    {
        //這裏就比較有說法了,由於順序式容器會使自己和後面的元素迭代器都失效,因此不能簡單的++操做
        //這裏順序式容器的erase()會返回緊隨被刪除元素的下一個元素的有效迭代器
        //而節點式容器的erase()的返回值是void,這點我感受太神奇了,確實太神奇了!!!!
        iter = mVector.erase(iter);
    }
    else
    {
        ++iter;
    }
}

 

注意:容器看具體STL庫的實現了,VS中兩類容器的earse都返回下一個迭代器指針。string

相關文章
相關標籤/搜索