C++:在迭代中刪除map的成員
阿新 • • 發佈:2019-01-07
首先要清楚一點,迭代器相當於是容器上的指標,容器可以自己管理記憶體,因此迭代器可能失效。
如果你在不知情的情況下使用了失效的迭代器,後果是不可預料的。可能程式立即崩掉,也可能什麼事都沒有發生。崩掉了算你幸運,因為你至少知道出了問題,不然有你受的。
回到正題,我想說什麼呢?
比如:
程式程式碼
map<string,int> theMap;
// add somethingto theMap...
for(auto iter1 = theMap.begin(); iter1 !=theMap.end(); ++iter1)
{
if(iter1->second == xxx)
{
theMap.erase(iter1); //#1erase the element ??!!
}
}
看樣子貌似非常正常的一段程式碼。在一個map中尋找值為xxx的項並刪除。
但是實際上這個程式碼是完全錯誤的,會導致無法預料的結果。
問題就在#1處。一旦你erase了一個iterator指向的內容,這個iterator就無效了。
這時候你再對這個iterator做任何操作其結果都是未定義的。
那麼該怎麼辦呢?
還好,對於map這種以指標構建起來的容器來說,可以保證一個元素刪除了,不影響指向其它元素的迭代器。
因此就可以這樣做(《C++Standard Library》上建議的正確做法):
for(auto iter1 = theMap.begin(); iter1 !=theMap.end(); )
{
if(iter1->second == xxx)
{
theMap.erase(iter1++); //#1
}else
{
++iter1;
}
}
這個遍歷把迭代器的自增從for頭部中取出,丟到迴圈體中去。#1處,iter1++這個運算先自增,但是卻返回了自增前的迭代器的一個臨時拷貝。然後這個臨時迭代器指向的內容被刪除了,但是iter1本身已經自增到下一個位置了,不受影響。