使用vector需謹慎!尤其是還沒有清楚vector的實現原理的時候!
標頭檔案中對於失效的檢測方式,定義是這樣的:
當erase了vector中的乙個元素後,不能保證原先指向有效位置的iterator仍然有效。
即:任何insert或push操作都可能導致迭代器失效。當編寫迴圈將元素插入到vector或deque容器中時,程式必須確保迭代器在每次迴圈後都得到更新。
vector::end返回的迭代器指向視窗最後乙個元素的後面乙個元素,這是乙個理論上的元素,並不指向容器中實際的元素。
所以不能對其進行解引用操作。
首先定義了兩個迭代器:
iter1
iter2
這兩個迭代器同時使用時,刪除vector元素會遇到的坑:
假定讓iter1從頭開始遍歷,用iter2刪除vector中的元素。為了保證不越界每次iter++之前,檢查iter1是否指向end。
但是每一次都報越界的錯誤。為什麼呢?
因為用iter2刪除的時候,可能刪除不止乙個。刪著刪著,iter1指向的位址被刪除了,iter1變成了野指標。你以為能夠檢查乙個野指標是否指向有效位址,而沒有考慮到檢察本身就需要開啟iter1,而對iter1解引用,肯定越界。
眾所周之,當使用乙個容器的insert或者erase函式通過迭代器插入或刪除元素"可能"會導致迭代器失效,因此,很多建議都是:讓我們獲取insert或者erase返回的迭代器,以便用重新獲取新的有效的迭代器進行正確的操作。
迭代器失效的原因如下:
當我們插入乙個元素時它的預分配空間不夠時,它會重新申請一段新空間,將原空間上的元素 複製到新的空間上去,然後再把新加入的元素放到新空間的尾部,以滿足vector元素要求連續儲存的目的。而後原空間會被系統撤銷或徵做他用,於是指向原 空間的迭代器就成了類似於「懸垂指標」一樣的東西,指向了一片非法區域。(對這種整體空間轉移的理解,類似於我的另一篇部落格c語言 realloc函式 帶著記憶體遊走的函式)
如果使用了這樣的迭代器,會導致嚴重的執行時錯誤就變得很自然了。這也是許多書上敘述vector在insert操作後「可能導致所有迭代器實效」的原因。
問題:按理說在l_vdata.end()前插入元素i後,it++,下次就又可以在l_vdata.end()前插入元素了,但是如果用it++,程式執行會出錯。為什麼?
#include
#include
void
main
(int argc,
char
** ar**)
system
("pause");
return
;}
vector的迭代器失效
大家知道vector容器與陣列的不同之處在於,vector可以自動擴容它的容量,是乙個動態的陣列,而我們的普通陣列的容量時固定死的。當vector內元素的數量等於vector容量的時候,再向vector中插入資料,vector會自動申請一塊兒更大的記憶體空間,並將原來的資料拷貝過去,並存將新的元素插...
vector迭代器失效
c 面試題經常會背問到vector和list的區別,其中就有乙個問題就困擾我們的,面試官說vector在進行插入和刪除元素的時候迭代器會失效,list不會,那這邊由我來給大家舉個列子 include include using namespace std int main include inclu...
vector迭代器失效的處理
1 這裡先給幾個我們經常遇到的問題 vs2012編譯器 include include using namespace std int main for vector iterator it a.begin it a.end it cout 這裡再呈現乙個問題 vectora for int i 0...