C 複習之迭代器失效的問題

2021-10-06 08:25:29 字數 2841 閱讀 9974

第一種場景:

首先咱們先用庫裡面自帶的vector容器,把容器中所有偶數刪除

#include 

#include

using namespace std;

int main()

//把容器中所有偶數刪除

auto it = vec.

begin()

;for

(; it != vec.

end();

++it)

}return0;

}

當我們執行程式之後,會發現程序意外中止。這是因為第一次呼叫erase之後,迭代器it就失效了 ,之後的for迴圈內的 ++it 操作就是出錯。

如果只刪除一次,則程序正常結束。

for

(; it != vec.

end();

++it)

}

原因是當你刪除乙個元素後,從這個元素的位置到容器結尾之間的迭代器全部失效。再進行++、–、!=等操作時,都會出現錯誤。

第二種場景

給容器內所有的偶數前面新增乙個小於偶數值1的數字

#include 

#include

using namespace std;

int main()

//給容器內所有的偶數前面新增乙個小於偶數值1的數字

auto it = vec.

begin()

;for

(; it != vec.

end();

++it)

}return0;

}

當我們執行程式之後,會發現程序意外中止。這是因為第一次呼叫erase之後,迭代器it就失效了 ,之後的for迴圈內的 ++it 操作就是出錯。

如果只插入一次,則程序正常結束。

即加入break。

auto it = vec.

begin()

;for

(; it != vec.

end();

++it)

}

增加也是一樣,原因是當你插入乙個元素後,如果容器不出現擴容的情況,從這個元素的插入位置到容器結尾之間的迭代器全部失效。再進行++、–、!=等操作時,都會出現錯誤。如果容器出現擴容的情況,系統會開闢乙個新的記憶體,在原來記憶體上儲存的所有迭代器都會失效。

迭代器為什麼會失效?

1.當容器呼叫erase方法後,當前位置到容器末尾元素的所有迭代器全部都失效了。

2.當容器呼叫insert方法後, 當前位置到容器末尾元素的所有迭代器全部都失效了。insert如果引起容器記憶體擴容,原來容器的所有的迭代器完全失效。

對插入/刪除點的迭代器進行更新操作

以刪除為例:當你將當前位置的元素刪除後,指向當前位置的迭代器就失效了,會在當前位置產生乙個新的迭代器iterator並返回。所以我們通過更新迭代器的方法來解決這個問題。

#include 

#include

using namespace std;

int main()

//第一次列印

for(int v : vec)

cout << endl;

//第一種場景刪除

//把容器中所有偶數刪除

auto it = vec.

begin()

;while

(it != vec.

end())

else

}#endif

//再次列印

for(int v : vec)

cout << endl;

return0;

}

以插入為例:

#include 

#include

using namespace std;

int main()

//第一次列印

for(int v : vec)

cout << endl;

//第二中場景插入

//給容器內所有的偶數前面新增乙個小於偶數值1的數字

auto it = vec.

begin()

;for

(; it != vec.

end();

++it)

}//再次列印

for(int v : vec)

cout << endl;

return0;

}

總結:迭代器失效分三種情況考慮,也是非三種資料結構考慮,分別為陣列型,鏈表型,樹型資料結構。

陣列型資料結構:該資料結構的元素是分配在連續的記憶體中,insert和erase操作,都會使得刪除點和插入點之後的元素挪位置,所以,插入點和刪除掉之後的迭代器全部失效,也就是說insert(*iter)(或erase(*iter)),然後在iter++,是沒有意義的。解決方法:erase(*iter)的返回值是下乙個有效迭代器的值。 iter =cont.erase(iter);

鏈表型資料結構:對於list型的資料結構,使用了不連續分配的記憶體,刪除運算使指向刪除位置的迭代器失效,但是不會失效其他迭代器.解決辦法兩種,erase(*iter)會返回下乙個有效迭代器的值,或者erase(iter++).

樹形資料結構: 使用紅黑樹來儲存資料,插入不會使得任何迭代器失效;刪除運算使指向刪除位置的迭代器失效,但是不會失效其他迭代器.erase迭代器只是被刪元素的迭代器失效,但是返回值為void,所以要採用erase(iter++)的方式刪除迭代器。

注意:經過erase(iter)之後的迭代器完全失效,該迭代器iter不能參與任何運算,包括iter++,*ite

C 迭代器 迭代器失效問題

問題描述 輸入乙個整數陣列,實現乙個函式來調整該陣列中數字的順序,使得所有的奇數字於陣列的前半部分,所有的偶數字於位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。這是劍指offer上的一道經典習題,我們首先可以想到的解決方案是 再建立乙個臨時陣列把偶數先存放起來,然後把臨時空間的...

C 迭代器失效問題

迭代器失效 1 對於在記憶體中連續分布的容器 vector queue deque 插入或者刪除會使插入或者刪除點的迭代器以及之後的迭代器失效。2。對於非連續儲存的容器 list,forword list,map 插入或刪除僅僅使插入或者刪除點迭代器失效。解決方法 1 對於連續記憶體容器或者非連續記...

C 迭代器失效問題

迭代器失效問題一般是指對於stl容器來說,呼叫erase某迭代器之後,就不能再使用這個iterator了。解決方法 1 erase iter 這樣可以繼續使用該iter 2 it erase iter 這是利用erase函式的返回值,一般的erase函式都會返回乙個刪除迭代器的後繼迭代器。如果是er...