C 容器作為引用傳參時導致的迭代器失效問題

2021-10-08 12:28:57 字數 2233 閱讀 6444

容器作為引用傳參可能導致迭代器失效

一、序列型容器

包括vector,deque,string等,其特點是元素儲存在連續記憶體中,插入和刪除會導致之後的元素移動,所以插入和刪除都會導致插入/刪除點及其之後的所有迭代器失效

在迴圈中刪除元素的正確寫法:

for

(auto it = nums.

begin()

; it != nums.

end();

)if(.

..) it = nums.

erase

(it)

;// erase返回下乙個有效的迭代器

else

++it;

二、關聯型容器

包括map,set,unordered_set等,其特點是使用紅黑樹來儲存元素,插入不會使任何迭代器失效,刪除會使指向刪除點的那乙個迭代器失效,其餘不會失效。

在迴圈中刪除元素的正確寫法:

for

(auto it = map.

begin()

; it != map.end;)if

(...

) map.

erase

(it++);

else it++

;

在c++ 98中,erase不會返回下乙個有效的迭代器,但在c++ 11標準中則會。因此,在新標準裡it = map.erase(it)也是可行的。

三、鏈表型容器

包括list等,其特點是元素儲存在不連續的記憶體中,插入不會使任何迭代器失效,刪除會使指向刪除點的那乙個迭代器失效,其餘不會失效。

在迴圈中刪除元素的正確寫法:

for

(auto it = list.

begin()

; it != list.end;)if

(...

) list.

erase

(it++);

//或者 it = list.erase(it)

else it++

;

總結

需要通過迭代器一邊遍歷一邊刪除元素時,一定不能直接讓迭代器遞增,it = stl.erase(it)適用於新標準中這3種型別的容器,stl.erase(it++)適用於關聯型和鏈表型容器。

今天在做leetcode第46題全排列時,我實現了回溯演算法,但**一直遇到段錯誤,如下:

class solution 

private:

void

dfs(vectorint>>

& result, vector<

int>

& permutation, list<

int>

& l)

for(

auto it = l.

begin()

; it != l.

end();

)}};

gdb顯示段錯誤發生在這兩行:

dfs

(result, permutation, l);l.

insert

(it, tmp)

;

雖然我在迴圈中刪除和插入鍊錶的元素,但我的寫法是正確的,不會導致迭代器的失效。我另外編寫了一段測試**,證明了這樣寫是沒問題的,那麼問題出在哪就令人百思不得其解了。

最終發現是由於list& l&導致的。我本來想利用引用傳參來節省記憶體和時間,畢竟執行完乙個dfs函式之後鍊錶中的元素是沒有變化的,但它卻導致了迭代器的失效。

l=[1,2]為例,按**中的邏輯,先要刪除1,此時it指向2,l=[2]傳入下一層dfs。在下一層dfs執行時,會刪除掉這個2,由於l是引用的,這個刪除操作導致了上一層dfs中的it失效,儘管之後會將2插入到原位置,看起來l中的元素沒有變化,但迭代器已經發生了改變。此時返回上一層dfs,再用it去插入元素,自然會引發段錯誤。

C 引用 和指標在作為形參時的區別

nt n int m n 在c 中,多了乙個c語言沒有的引用宣告符 如上,m就是n的引用,簡單的說m就是n的別名,兩者在記憶體中佔同樣的位置,不對m開闢新的記憶體空間,對m的任何操作,對n來說是一樣的。對於引用,有以下三條規則 1 引用被建立的同時必須被初始化 指標則可以在任何時候被初始化 2 不能...

C 引用 和 指標 在作為形參時的區別

一 熱身準備 int n int m n 在c 中,多了乙個c語言沒有的引用宣告符 如上,m就是n的引用,簡單的說m就是n的別名,兩者在記憶體中佔同樣的位置,不對m開闢新的記憶體空間,對m的任何操作,對n來說是一樣的。二 對於引用,有以下三條規則 1 引用被建立的同時必須被初始化 指標則可以在任何時...

std中list作為常量傳參時乙個迭代器錯誤

如果list作為常量引數傳入函式時,使用list的迭代器要注意,如果 這樣寫 ostream operator ostream ostr,const list li return ostr error conversion from std list const iterator to non sc...