本文只總結常見的序列容器(vector、deque、list)和關聯容器(set、multiset、map、multimap)的迭代器失效問題。
原迭代器指的是進行操作之前儲存的迭代器,包括begin()、end()以及其他位置的迭代器。
vector:
成員函式push_back():會在容器末尾新增乙個元素。如果容器有剩餘空間(capacity() > size()),則直接新增新元素到容器尾部。此時,原迭代器中end()會失效,其他的都不會失效。否則,會導致容器重新分配記憶體,然後將資料從原記憶體複製到新記憶體,再在尾部新增新元素。此時,由於記憶體重新分配,原迭代器(所有)都失效。
成員函式pop_back():直接將容器中的最後乙個元素刪除,原迭代器中end()會失效,其餘的都不會失效。
成員函式insert(iterator, n):如果容器有剩餘空間,先在容器尾部插入乙個元素,然後將插入點及之後的元素都向後移動一位,然後在插入點建立新元素。否則,會導致容器重新分配記憶體,接著將插入點之前的元素複製過去,在插入點建立新元素,再將插入點之後的元素複製過去。因此,如果沒有記憶體的重新分配,原迭代器中插入點及插入點之後的迭代器(包括end())都失效。如果有記憶體的重新分配,原迭代器(所有)都失效。
成員函式erase(iterator):將刪除點及之後的元素都向前移動一位,然後刪除最後乙個元素。因此,原迭代器中刪除點之前的迭代器都有效,插入點及插入點之後的迭代器都失效。
deque:
成員函式push_back():會直接在容器末尾新增乙個元素。原迭代器中end()會失效,其他的都不會失效。
成員函式push_front():會直接在容器頭部新增乙個元素。原迭代器中begin()會失效,其他的都不會失效。
成員函式pop_back():會直接刪除最後乙個元素。原迭代器中end()會失效,其他的都不會失效
成員函式pop_front():會直接在容器頭部刪除乙個元素。原迭代器中begin()會失效,其他的都不會失效。
成員函式insert(iterator, n):如果插入點之前的元素較少,會在容器頭部插入乙個元素,然後將插入點及其之前的所有元素向前移動一位,再在插入點建立新元素。否則,將插入點及其之後的元素向後移動一位,再在插入點建立新元素。因此,向前移動則導致原迭代器中插入點及插入點之前的迭代器都失效;向後移動則導致迭代器中插入點及插入點之後的迭代器都失效。
成員函式erase(iterator):如果刪除點之前的元素較少,將刪除點之前的所有元素向後移動一位,再刪除第乙個元素。否則,將刪除點之後的所有元素向前移動一位,再刪除最後乙個元素。因此,向前移動將導致原迭代器中刪除點及刪除點之後的迭代器失效;向後移動將導致原迭代器中刪除點及刪除點之前的迭代器都失效。
list:
因為list的底層結構是雙向鍊錶,所有操作都只是針對節點移動指標,不會涉及到位置變化,操作影響的範圍很小。
成員函式push_back():原迭代器中end()會失效,其他的都不會失效。
成員函式push_front():原迭代器中begin()會失效,其他的都不會失效。
成員函式pop_back():原迭代器中end()會失效,其他的都不會失效
成員函式pop_front():原迭代器中begin()會失效,其他的都不會失效。
成員函式insert(iterator, n):原迭代器中插入點會失效,其他的都不會失效。
成員函式erase(iterator):原迭代器中刪除點會失效,其他的都不會失效。
set、multiset、map、multimap
關聯容器的底層結構為紅黑樹,所有操作同list一樣,都只是移動指標,各成員函式導致的迭代器失效問題同list。
注意:文中成員函式的內部實現以sgi stl為準。
STL容器特徵總結和迭代器失效
內部資料結構 連續儲存,例如陣列。隨機訪問每個元素,所需要的時間為常量。在末尾增加或刪除元素所需時間與元素數目無關,在中間或開頭增加或刪除元素所需時間隨元素數目呈線性變化。可動態增加或減少元素,記憶體管理自動完成,但程式設計師可以使用reserve 成員函式來管理記憶體。迭代器失效 插入 vecto...
STL容器特徵總結與迭代器失效
內部資料結構 連續儲存,例如陣列。隨機訪問每個元素,所需要的時間為常量。在末尾增加或刪除元素所需時間與元素數目無關,在中間或開頭增加或刪除元素所需時間隨元素數目呈線性變化。可動態增加或減少元素,記憶體管理自動完成,但程式設計師可以使用reserve 成員函式來管理記憶體。迭代器失效 插入 vecto...
STL容器迭代器失效問題
眾所周知當使用乙個容器的insert或者erase函式通過迭代器插入或刪除元素 可能 會導致迭代器失效,因此很多建議都是讓我們獲取insert或者erase返回的迭代器,以便用重新獲取新的有效的迭代器進行正確的操作 view plaincopy to clipboardprint?iter vec....