C 之迭代器失效總結

2022-06-17 20:42:15 字數 2740 閱讀 2805

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()

vector::iterator iter;

for (iter = container.begin(); iter != container.end();)

else

}for (iter = container.begin(); iter != container.end(); iter++)

}

這樣刪除後iter指向的元素後,返回的是下乙個元素的迭代器,這個迭代器是vector記憶體調整過後新的有效的迭代器。

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(); )

else

}

map::iterator tmpiter =iter; iter++;

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....