STL中erase 用法陷阱

2021-05-27 17:43:39 字數 1375 閱讀 8680

erase()函式的功能是用來刪除容器中的元素

刪除某個容器裡的某個元素:c.erase(t);

看似乙個簡單的動作,然而對不同型別的容器,內部卻做了截然不同的事情,後面介紹。

假設有這樣乙個題目,將某個容器中所有滿足條件n == x的元素刪除,按照常規的思路應該有類似這樣的**: //

假設container和container分別表示一種容器和對應的乙個物件

container

<

t>

::iterator it;

for(it 

=container.begin(); it 

!=container.end(); 

++it) 

然而這樣的**對於任一種容器都是錯誤的

容器按記憶體分配方式可以分為鍊錶容器和陣列容器。

所謂的鍊錶容器指的是一種表現方式,包括list、slist等這樣基於節點的容器(動態分配記憶體塊)和set、map、multiset、multimap等關聯容器(平衡樹實現),而陣列容器指的是在一塊連續的記憶體上儲存元素的連續記憶體容器,比如vector、deque、string等。

鍊錶容器以list為例,當執行container.erase(it)時,確實第乙個滿足條件的元素刪除了,但這時it指標已經被刪除了,它也不指向任何元素了,所以也只能到此為止了,也就是說上面的**對於鍊錶容器來說只能正確刪除第乙個滿足條件的元素,針對這個問題我們首先想到的就是在刪除指標之前,給其做個備份。

將這個臨時變數直接建立在erase實現裡,這樣做更簡潔,也顯得專業些。

list<

int>

::iterator it; 

for(it 

=lt.begin(); it 

!=lt.end(); ) 

鍊錶容器使用erase刪除節點還有乙個特點,就是會將下乙個元素的位址返回,所以也可以這樣實現:

list<

int>

::iterator it; 

for(it 

=lt.begin(); it 

!=lt.end(); ) 

陣列容器以vector為例,當執行container.erase(it)時,和上面提到的一樣,第乙個滿足條件的元素刪除了,但這時陣列容器不允許中間有「空隙」,所以會做個大動作,就是將被刪元素後面所有的元素前移(參考stl原始碼),而陣列容器記錄的是下標,所以刪除元素後,當前下標定位的元素也就順理成章的變成了原有佇列中的下乙個元素,同樣以刪除偶數為例,**如下:

vector<

int>

::iterator it 

=v.begin();

for(it 

=v.begin(); it 

!=v.end(); ) 

STL中erase 的陷阱

最近在刷stl原始碼剖析這本書時,對於vector的erase 函式引起了我的注意 在刪除單個元素時是這樣定義的 iterator erase iterator position finish destroy finish return position erase 將position 1後面的元素...

STL中remove 和erase 的用法

示例 initializer listlist t vectorvec list t vector iterator it for it vec.begin it vec.end it cout endl remove vec.begin vec.end 1 for it vec.begin it ...

STL的erase 陷阱 迭代器失效總結

下面材料整理自internet 著作。stl中的容器按儲存方式分為兩類,一類是按以陣列形式儲存的容器 如 vector deque 另一類是以不連續的節點形式儲存的容器 如 list set map 在使用erase方法來刪除元素時,需要注意一些問題。1.list,set,map容器 在使用 lis...