STL原始碼剖析 迭代器失效小結

2021-09-30 10:28:41 字數 1536 閱讀 6902

**:

迭代器(iterator)是乙個可以對其執行類似指標的操作(如:解除引用(operator*())和遞增(operator++()))的物件,我們可以將它理解成為乙個指標。但它又不是我們所謂普通的指標,我們可以稱之為廣義指標,你可以通過sizeof(vector::iterator)來檢視,所佔記憶體並不是4個位元組。

首先對於vector而言,新增和刪除操作可能使容器的部分或者全部迭代器失效。那為什麼迭代器會失效呢?vector元素在記憶體中是順序儲存,試想:如果當前容器中已經存在了10個元素,現在又要新增乙個元素到容器中,但是記憶體中緊跟在這10個元素後面沒有乙個空閒空間,而vector的元素必須順序儲存一邊索引訪問,所以我們不能在記憶體中隨便找個地方儲存這個元素。於是vector必須重新分配儲存空間,用來存放原來的元素以及新新增的元素:存放在舊儲存空間的元素被複製到新的儲存空間裡,接著插入新的元素,最後撤銷舊的儲存空間。這種情況發生,一定會導致vector容器的所有迭代器都失效。

我們看到實現上述所說的分配和撤銷記憶體空間的方式以實現vector的自增長性,效率是極其低下的。為了使vector容器實現快速的記憶體分配,實際分配的容器會比當前所需的空間多一些,vector容器預留了這些額外的儲存區,用來存放新新增的元素,而不需要每次都重新分配新的儲存空間。你可以從vector裡實現capacity和reserve成員可以看出這種機制。

capacity和size的區別:size是容器當前擁有的元素個數,而capacity則指容器在必須分配新儲存空間之前可以儲存的元素總數。

vector迭代器的幾種失效的情況: 

deque迭代器的失效情況: 在c++primer一書中是這樣限定的: 

1、在deque容器首部或者尾部插入元素不會使得任何迭代器失效。 

2、在其首部或尾部刪除元素則只會使指向被刪除元素的迭代器失效。

3、在deque容器的任何其他位置的插入和刪除操作將使指向該容器元素的所有迭代器失效。但是:我在vs2005測試發現第一條都不滿足,不知為何?等以後深入stl以後慢慢的領會吧!

只有list的迭代器好像很少情況下會失效。也許就只是在刪除的時候,指向被刪除節點的迭代器會失效吧,其他的還沒有發現。

先看兩條規制:

1、對於節點式容器(map, list, set)元素的刪除,插入操作會導致指向該元素的迭代器失效,其他元素迭代器不受影響。

2、對於順序式容器(vector)元素的刪除、插入操作會導致指向該元素以及後面的元素的迭代器失效。

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

**如下:

[cpp]view plain

copy

print?

iter = vec.insert(iter);  

iter = vec.erase(iter);  

iter = vec.insert(iter);

iter = vec.erase(iter);

STL原始碼剖析 迭代器失效小結

deque迭代器的失效情況 在c primer一書中是這樣限定的 1 在deque容器首部或者尾部插入元素不會使得任何迭代器失效。2 在其首部或尾部刪除元素則只會使指向被刪除元素的迭代器失效。3 在deque容器的任何其他位置的插入和刪除操作將使指向該容器元素的所有迭代器失效。但是 我在vs2005...

STL原始碼剖析 迭代器失效小結

deque迭代器的失效情況 在c primer一書中是這樣限定的 1 在deque容器首部或者尾部插入元素不會使得任何迭代器失效。2 在其首部或尾部刪除元素則只會使指向被刪除元素的迭代器失效。3 在deque容器的任何其他位置的插入和刪除操作將使指向該容器元素的所有迭代器失效。但是 我在vs2005...

STL原始碼剖析 迭代器失效小結

deque迭代器的失效情況 在c primer一書中是這樣限定的 1 在deque容器首部或者尾部插入元素不會使得任何迭代器失效。2 在其首部或尾部刪除元素則只會使指向被刪除元素的迭代器失效。3 在deque容器的任何其他位置的插入和刪除操作將使指向該容器元素的所有迭代器失效。但是 我在vs2005...