STL 注意事項

2021-07-26 16:49:30 字數 1652 閱讀 1703

stl中的容器的儲存分為順序儲存(如vector、deque)與鏈式儲存(如list、map、set)。

對於map與list這樣的鏈式儲存結構。我們一般可以有兩種方法

1. 使用erase(iter++),因為iter2 = iter++是iter先移到指向下乙個節點,而iter2還是指向當前的節點。

for(;iter!=mapstudent.end();)

else

}這種刪除方式也是stl原始碼一書中推薦的方式,分析 mapstudent.erase(iter++)語句,map中在刪除iter的時候,先將iter做快取,然後執行iter++使之指向下乙個結點,再進入erase函式體中執行刪除操作,刪除時使用的iter就是快取下來的iter(也就是當前iter(做了加操作之後的iter)所指向結點的上乙個結點)。

根據以上分析,可以看出mapstudent.erase(iter++)和map student.erase(iter); iter++;這個執行序列是不相同的。前者在erase執行前進行了加操作,在iter被刪除(失效)前進行了加操作,是安全的;後者是在erase執行後才進行加操作,而此時iter已經被刪除(當前的迭代器已經失效了),對乙個已經失效的迭代器進行加操作,行為是不可預期的,這種寫法勢必會導致 map操作的失敗並引起程序的異常。

2. erase的返回值會指向下乙個節點

for(tstrmapiter iter= strmap.begin(); iter!= strmap.end();)  

else  

}  但對於順序儲存第一種用法卻是錯誤的。因為順序儲存的容器一旦erase時,會涉及到資料移動,iterator所指的位置還是那個位置,但元素卻移動了,iter++之後已不再你想要的元素位置了。iter = strmap.erase(iter)與iter++對於順序容器有何不同?

原始碼剖析

以stl list為例:

iterator的相關操作

_self& operator++()

_self operator++(int)

void _m_incr()  

//++的操作對於list結構來說,就是使iterator的_m_node指向下乙個結點

iterator erase(iterator __position)

分析**我們可以看出,erase會deallocate__position的_m_node, 在__position上再進行++是錯誤的。

所以不能在m_list.erase(iter)後,進行iter++.

哪為什麼m_list.erase(iter++)可以呢?為什麼不能用m_list.erase(++iter)?

參照operator++的**我們可以找到答案,iter++返回了++之前的iter值,erase使用這個值能正確進行__position的前後結點的串接及刪除正確的結點,而++iter返回的是++之後的iter,所以m_list.erase(++iter)串接不正確,iter->_m_node也是失效的.

對於非結點類,如陣列類的容器vector,string,deque,如果erase會返回下個有效的iterator,可以這樣處理:

for(vector::iterator iter = m_vector.begin(); iter != m_vector.end();)

else

++iter;

}

STL庫中的queue使用注意事項

當使用stl的queue時,元素入隊的push操作只是製造了該元素的乙個副本入隊 因此在入隊後對原元素的修改不會影響佇列中的副本 而佇列中副本的修改也不會改變原元素,需要注意由此可能引入的bug 一般由結構體產生 所以是啥bug?include include using namespace std...

java DOM 注意事項

1.w3c把標籤內的文字部分也定義成乙個node 2.element物件代表的是xml文件中的標籤元素 繼承於node,亦是node的最主要的子物件 3.attr實際上是包含在element中的,它並不能被看作是element的子物件,因而在dom中attr並不是dom樹的一部分,所以node中的 ...

static注意事項

static關鍵字是c,c 中都存在的關鍵字,它主要有三種使用方式,其中前兩種只指在c語言中使用,第三種在c 中使用 c,c 中具體細微操作不盡相同,本文以c 為準 1 區域性靜態變數 2 外部靜態變數 函式 3 靜態資料成員 成員函式 下面就這三種使用方式及注意事項分別說明 一 區域性靜態變數 在...