迭代器什麼時候失效
vector迭代器什麼時候會失效?
一、 push_back導致迭代器失效
vector在push_back的時候當容量不足時會觸發擴容,導致整個vector重新申請記憶體,並且將原有的資料複製到新的記憶體中,並將原有記憶體釋放,這自然是會導致迭代器失效的,因為迭代器所指的記憶體都已經被釋放。
二、insert導致迭代器失效
insert導致的迭代器失效有兩種情況:
(1)插入操作導致vector擴容,迭代器失效原因和push_back相同
(2)插入操作引起vector內元素移動,導致被移動部分的迭代器失效
三、erase導致迭代器失效
刪除操作引起vector內元素移動,導致被移動部分的迭代器失效。
關聯性容器迭代器何時失效?
對於關聯容器(如map, set,multimap,multiset),刪除當前的iterator,僅僅會使當前的iterator失效,只要在erase時,遞增當前iterator即可。這是因為map之類的容器,使用了紅黑樹來實現,插入、刪除一個結點不會對其他結點造成影響。erase迭代器只是被刪元素的迭代器失效,但是返回值為void,所以要採用erase(iter++)的方式刪除迭代器。
連結串列式容器迭代器何時失效?
對於連結串列式容器(如list),刪除當前的iterator,僅僅會使當前的iterator失效,這是因為list之類的容器,使用了連結串列來實現,插入、刪除一個結點不會對其他結點造成影響。只要在erase時,遞增當前iterator即可,並且erase方法可以返回下一個有效的iterator。
四、總結
迭代器失效分三種情況考慮,也是分三種資料結構考慮,分別為陣列型,連結串列型,樹型資料結構。
陣列型資料結構:該資料結構的元素是分配在連續的記憶體中,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