迭代器(游標)是乙個奇特的東西,它是乙個指標,用來指向stl容器中的元素,也可以指向其他的元素,其是提供一種方法訪問乙個容器,比如說vector、list、map、deque等容器。
在我們的日常生活中,當使用它時,大家一不小心就會犯乙個錯誤,那就是使用中導致迭代器會失效。今天我們主要說說迭代器失效的幾種情況和解決方法。
一、對於順序容器vector、deque、array等刪除當前的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 iter;
for (iter = container.begin(); iter != container.end();)
for (iter = container.begin(); iter != container.end(); iter++)
}
解析:datamap.erase(iter)之後,iter就已經失效了,所以iter無法自增,即iter++就會出bug.解決方案,就是在iter失效之前,先自增。
for (iter = datamap.begin(); iter != datamap.end();iter++)
else
iter++;
}
這幾句的意思是,先保留要刪除的節點迭代器,再讓iter向下乙個有意義的節點,然後刪除節點。所以這個操作結束後iter指向的是下乙個有意義的節點,沒有失效。map是關聯容器,以紅黑樹或者平衡二叉樹組織資料,雖然刪除了乙個元素,整棵樹也會調整,以符合紅黑樹或者二叉樹的規範,但是單個節點在記憶體中的位址沒有變化,變化的是各節點之間的指向關係。其實這三句話可以用在一句話代替,就是datamap.erase(iter++);
解釋:先讓iter指向下乙個有效的節點,但是返回給erase函式的是原來的iter副本。這個可能跟++這個操作的本身語法相關。
最後總結以下三種失效的情況:
1.陣列型資料結構:該資料結構的元素是分配在連續的記憶體中,insert和erase操作,都會使得刪除點和插入點之後的元素挪位置,所以,插入點和刪除掉之後的迭代器全部失效,也就是說insert(*iter)(或erase(*iter)),然後在iter++,是沒有意義的。解決方法:erase(*iter)的返回值是下乙個有效迭代器的值。 iter =cont.erase(iter);
2.鏈表型資料結構:對於list型的資料結構,使用了不連續分配的記憶體,刪除運算使指向刪除位置的迭代器失效,但是不會失效其他迭代器.解決辦法兩種,erase(*iter)會返回下乙個有效迭代器的值,或者erase(iter++).
3.樹形資料結構: 使用紅黑樹來儲存資料,插入不會使得任何迭代器失效;刪除運算使指向刪除位置的迭代器失效,但是不會失效其他迭代器.erase迭代器只是被刪元素的迭代器失效,但是返回值為void,所以要採用erase(iter++)的方式刪除迭代器
迭代器失效 典型的迭代器失效
首先對於vector而言,新增和刪除操作可能使容器的部分或者全部迭代器失效。那為什麼迭代器會失效呢?vector元素在記憶體中是順序儲存,試想 如果當前容器中已經存在了10個元素,現在又要新增乙個元素到容器中,但是記憶體中緊跟在這10個元素後面沒有乙個空閒空間,而vector的元素必須順序儲存一邊索...
迭代器失效
迭代器 iterator 是乙個可以對其執行類似指標的操作 如 解除引用 operator 和遞增 operator 的物件,我們可以將它理解成為乙個指標。但它又不是我們所謂普通的指標,我們可以稱之為廣義指標,你可以通過sizeof vector iterator 來檢視,所佔記憶體並不是4個位元組...
迭代器失效
對於序列式容器 如vector,deque 刪除當前的iterator會使後面所有元素的iterator都失效。這是因為vetor,deque使用了連續分配的記憶體,刪除乙個元素導致後面所有的元素會向前移動乙個位置。所以不能使用erase iter 的方式,還好erase方法可以返回下乙個有效的it...