STL迭代器失效總結



    

      迭代器(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迭代器的幾種失效的狀況:

一、當插入(push_back)一個元素後,end操做返回的迭代器確定失效。

二、當插入(push_back)一個元素後,capacity返回值與沒有插入元素以前相比有改變,則須要從新加載整個容器,此時first和end操做返回的迭代

器都會失效。

三、當進行刪除操做(erase,pop_back)後,指向刪除點的迭代器所有失效;指向刪除點後面的元素的迭代器也將所有失效。

deque迭代器的失效狀況 

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

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

三、在deque容器的任何其餘位置的插入和刪除操做將使指向該容器元素的全部迭代器失效。

先看兩條規制:

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

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

衆所周之當使用一個容器的insert或者erase函數經過迭代器插入或刪除元素"可能"會致使迭代器失效,所以不少建議都是讓咱們獲取insert或者

erase返回的迭代器,以便用從新獲取新的有效的迭代器進行正確的操做:

代碼以下:

   
   
   
   
iter = vec.insert(iter);iter = vec.erase(iter);

關於deque迭代器:

deque是一種優化了的對序列兩端元素進行添加和刪除操做的基本序列容器。一般由一些獨立的區塊組成,第一區塊朝某方向擴展,最後一個區塊

朝另外一方向擴展。它容許較爲快速地隨機訪問但它不像vector同樣把全部對象保存在一個連續的內存塊,而是多個連續的內存塊。而且在一個映射

結構中保存對這些塊以及順序的跟蹤。







相關文章
相關標籤/搜索