STL 迭代器失效問題

2021-06-21 06:18:22 字數 1866 閱讀 9378

最近在專案開發中,遇到乙個異常,經過測試,發現是迭代器失效問題,於是稍微總結了一下。

vector迭代器失效測試:

測試程式: 

void vectortest()

vector<

int>::iterator iter;

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

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

vector<

int>::iterator iter;

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

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

cout<<

"map元素內容為:

"string>::iterator iter;

for (iter = datamap.begin(); iter != datamap.end(); iter++)

cout

結果報錯:

看看報異常時跟進去在**報錯:

根據迭代器訪問資料時失效! map/set iterator not dereferencable

迭代器是不引用的。

正確的做法是: 

void maptest()

cout<<

"map元素內容為:

"string>::iterator iter;

for (iter = datamap.begin(); iter != datamap.end(); iter++)

else

if (iter != datamap.end())

cout

最後輸出結果:

程式在一邊刪除一遍輸出,而且能夠順利輸出結束。

總結一下:

vector是乙個順序容器,在記憶體中是一塊連續的記憶體,當刪除乙個元素後,記憶體中的資料會發生移動,以保證資料的緊湊。所以刪除乙個資料後,其他資料的位址發生了變化,之前獲取的迭代器根據原有的資訊就訪問不到正確的資料。

所以為了防止vector迭代器失效,常用如下方法:

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

}

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

map是關聯容器,以紅黑樹或者平衡二叉樹組織資料,雖然刪除了乙個元素,整棵樹也會調整,以符合紅黑樹或者二叉樹的規範,但是單個節點在記憶體中的位址沒有變化,變化的是各節點之間的指向關係。

所以在map中為了防止迭代器失效,在有刪除操作時,常用如下方法:

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

else }

其中,

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

datamap.erase(tmpiter);

這幾句的意思是,先保留要刪除的節點迭代器,再讓

iter

向下乙個有意義的節點,然後刪除節點。

所以這個操作結束後iter指向的是下乙個有意義的節點,沒有失效。

其實這三句話可以用在一句話代替,就是datamap.erase(iter++);

解釋是先讓iter指向下乙個有效的節點,但是返回給erase函式的是原來的iter副本。這個可能跟++這個操作的本身語法相關。

但是功能跟上面是一樣的。

STL容器迭代器失效問題

眾所周知當使用乙個容器的insert或者erase函式通過迭代器插入或刪除元素 可能 會導致迭代器失效,因此很多建議都是讓我們獲取insert或者erase返回的迭代器,以便用重新獲取新的有效的迭代器進行正確的操作 view plaincopy to clipboardprint?iter vec....

STL迭代器失效的問題

內部資料結構 連續儲存,例如陣列。隨機訪問每個元素,所需要的時間為常量。在末尾增加或刪除元素所需時間與元素數目無關,在中間或開頭增加或刪除元素所需時間隨元素數目呈線性變化。可動態增加或減少元素,記憶體管理自動完成,但程式設計師可以使用reserve 成員函式來管理記憶體。迭代器失效 插入 vecto...

STL容器迭代器失效問題

眾所周知當使用乙個容器的insert或者erase函式通過迭代器插入或刪除元素 可能 會導致迭代器失效,因此很多建議都是讓我們獲取insert或者erase返回的迭代器,以便用重新獲取新的有效的迭代器進行正確的操作 view plaincopy to clipboardprint?iter vec....