1. 對於序列式容器(如vector,deque),序列式容器就是陣列式容器,刪除當前的iterator會使後面所有元素的iterator都失效。這是因為vetor,deque使用了連續分配的記憶體,刪除乙個元素導致後面所有的元素會向前移動乙個位置。所以不能使用erase(iter++)的方式,還好erase方法可以返回下乙個有效的iterator。
for (iter = cont.begin(); iter != cont.end();)迭代器失效:
void vectortest()迭代器在執行++操作時報錯!已經失效的迭代器不能再進行自增運算了。vector::iterator iter;
for (iter = container.begin(); iter != container.end(); iter++)
for (iter = container.begin(); iter != container.end(); iter++)
對於序列式容器,比如vector,刪除當前的iterator會使後面所有元素的iterator都失效。這是因為順序容器記憶體是連續分配(分配乙個陣列作為記憶體),刪除乙個元素導致後面所有的元素會向前移動乙個位置。(刪除了乙個元素,該元素後面的所有元素都要挪位置,所以,iter++,已經指向的是未知記憶體)。
但是erase方法可以返回下乙個有效的iterator。所以**做如下修改,就ok了。
void vectortest()這樣刪除後iter指向的元素後,返回的是下乙個元素的迭代器,這個迭代器是vector記憶體調整過後新的有效的迭代器。vector::iterator iter;
for (iter = container.begin(); iter != container.end();)
else
}for (iter = container.begin(); iter != container.end(); iter++)
}
1. 對於關聯容器(如map, set,multimap,multiset),刪除當前的iterator,僅僅會使當前的iterator失效,只要在erase時,遞增當前iterator即可。這是因為map之類的容器,使用了紅黑樹來實現,插入、刪除乙個結點不會對其他結點造成影響。erase迭代器只是被刪元素的迭代器失效,但是返回值為void,所以要採用erase(iter++)的方式刪除迭代器。
for (iter = cont.begin(); it != cont.end();)void maptest()
cout<
for (iter = datamap.begin(); iter != datamap.end(); iter++)
/* cout
解析:datamap.erase(iter)之後,iter就已經失效了,所以iter無法自增,即iter++就會出bug.解決方案,就是在iter失效之前,先自增。
void maptest()
cout<
for (iter = datamap.begin(); iter != datamap.end(); iter++)
else }}
解析:datamap.erase(iter++);這句話分三步走,先把iter傳值到erase裡面,然後iter自增,然後執行erase,所以iter在失效前已經自增了。
map是關聯容器,以紅黑樹或者平衡二叉樹組織資料,雖然刪除了乙個元素,整棵樹也會調整,以符合紅黑樹或者二叉樹的規範,但是單個節點在記憶體中的位址沒有變化,變化的是各節點之間的指向關係。
所以在map中為了防止迭代器失效,在有刪除操作時,常用如下方法:
for (iter = datamap.begin(); iter != datamap.end(); )map::iterator tmpiter =iter; iter++;else
}
datamap.erase(tmpiter);
這幾句的意思是,先保留要刪除的節點迭代器,再讓iter向下乙個有意義的節點,然後刪除節點。
所以這個操作結束後iter指向的是下乙個有意義的節點,沒有失效。
其實這三句話可以用在一句話代替,就是datamap.erase(iter++);
但是功能跟上面是一樣的。
總結:迭代器失效分三種情況考慮,也是非三種資料結構考慮,分別為陣列型,鏈表型,樹型資料結構。
陣列型資料結構:該資料結構的元素是分配在連續的記憶體中,insert和erase操作,都會使得刪除點和插入點之後的元素挪位置,所以,插入點和刪除掉之後的迭代器全部失效,也就是說insert(*iter)(或erase(*iter)),然後在iter++,是沒有意義的。解決方法:erase(*iter)的返回值是下乙個有效迭代器的值。 iter =cont.erase(iter);
鏈表型資料結構:對於list型的資料結構,使用了不連續分配的記憶體,刪除運算使指向刪除位置的迭代器失效,但是不會失效其他迭代器.解決辦法兩種,erase(*iter)會返回下乙個有效迭代器的值,或者erase(iter++).
樹形資料結構: 使用紅黑樹來儲存資料,插入不會使得任何迭代器失效;刪除運算使指向刪除位置的迭代器失效,但是不會失效其他迭代器.erase迭代器只是被刪元素的迭代器失效,但是返回值為void,所以要採用erase(iter++)的方式刪除迭代器。
注意:經過erase(iter)之後的迭代器完全失效,該迭代器iter不能參與任何運算,包括iter++,*ite
C 迭代器失效情況總結
迭代器失效分三種情況考慮,也是分三種資料結構考慮,分別為陣列型,鏈表型,樹型資料結構。陣列型資料結構 該資料結構的元素是分配在連續的記憶體中,insert和erase操作,都會使得刪除點和插入點之後的元素挪位置,所以,插入點和刪除掉之後的迭代器全部失效,也就是說insert iter 或erase ...
C 迭代器失效
眾所周知當使用乙個容器的insert或者erase函式通過迭代器插入或刪除元素 可能 會導致迭代器失效,因此很多建議都是讓我們獲取insert或者erase返回的迭代器,以便用重新獲取新的有效的迭代器進行正確的操作 view plaincopy to clipboardprint?iter vec....
c 迭代器失效
眾所周知當使用乙個容器的insert或者erase函式通過迭代器插入或刪除元素 可能 會導致迭代器失效,因此很多建議都是讓我們獲取insert或者erase返回的迭代器,以便用重新獲取新的有效的迭代器進行正確的操作 view plaincopy to clipboardprint?iter vec....