C++之vector中元素刪除
今天在刪除vector中的元素中遇到一個問題,這裡記錄下來以便以後查閱。
預備知識:用到了erase()函數,對於一個容器c來說,假設迭代器為p,那麼執行:
c.erase(p)之後就刪除了容器c中p所指向的元素,並且返回一個迭代器,返回的迭代器指向剛才所刪除元素後面的一個元素(這裡是關鍵)!
有了上面的知識後,我編寫了下面的代碼(頭文件略去),刪去矢量vals中的1:
復制代碼
1 int main()
2 {
3 vector<int> vals;
4 vals.push_back(1);
5 vals.push_back(2);
6 vals.push_back(2);
7 vals.push_back(1);
8 vals.push_back(2);
9 vals.push_back(3);
10 vals.push_back(3);
11 vals.push_back(4);
12
13 vector<int>::iterator itr = vals.begin();
14
15 while ( itr != vals.end())
16 {
17 if (1 == *itr)
18 {
19 vals.erase(itr);
20 }
21 else
22 ++itr;
23 }
24 itr = vals.begin();
25
26 while(itr != vals.end())
27 {
28 cout << *itr << endl;
29 itr++;
30 }
31 return 0;
32 }
復制代碼
編譯通過,但是調試就報錯:
所以我進行了斷點調試,發現第一個1可以成功刪除,但是第二次試圖遍歷vals的時候,就會報錯,看半天代碼,無果,在網上搜了一些帖子,終於知道,原來,容器在刪除或者插入一個元素之後,原來的迭代器會失效,於是第二次遍歷時的判斷條件還繼續用原來的迭代器,系統無法判斷是什麼東西,於是報錯,怎麼解決呢?但是C++設計者早就為我們鋪好了路,雖然erase()使得原來的迭代器失效了,但是上面說過,erase()會返回一個迭代器,返回的迭代器指向剛才所刪除元素後面的一個元素,於是我們就要利用好這個返回的迭代器,更改代碼如下:
就是把上面代碼中的第19行改為:
itr = vals.erase(itr);
這樣,原來的迭代器失效了,但是返回的迭代器又重新賦給了itr,於是工作可以繼續
所以說看一百遍不如自己親自實踐一遍,看似簡單的問題,沒想到花了如此長的時間,事無巨細,實踐為真!