C++迭代器失效的避坑指南
1. 什么是迭代器失效?
在 C++ 中,迭代器(iterator) 是一種類似指針的對象,用于遍歷 STL 容器(如 vector、list、map 等)。
迭代器失效是指在對容器進行某些操作(如插入、刪除)后,原本有效的迭代器變得不可用,繼續(xù)使用它會導致 未定義行為(Undefined Behavior, UB),如程序崩潰、數(shù)據(jù)錯誤等
2. 哪些操作會導致迭代器失效?
不同的容器有不同的迭代器失效規(guī)則,本文主要討論 vector 的迭代器失效問題。
2.1 vector 的插入操作(push_back, insert)
當向 vector 插入元素時:
- 如果
size() == capacity()(容量已滿):vector會重新分配更大的內(nèi)存,并拷貝原有數(shù)據(jù)。- 所有迭代器失效(包括
begin(),end()等)。
- 如果
size() < capacity()(容量未滿):- 插入點之前的迭代器仍然有效。
- 插入點及之后的迭代器失效(因為元素可能被移動)。
示例:push_back 導致迭代器失效
vector<int> v = {1, 2, 3};
auto it = v.begin(); // it 指向 1
v.push_back(4); // 可能觸發(fā)重新分配內(nèi)存
cout << *it; // ? 危險!it 可能失效如何避免?
- 提前預留空間(
reserve()):
vector<int> v; v.reserve(100); // 預留 100 個元素的空間 auto it = v.begin(); v.push_back(1); // 不會重新分配,it 仍然有效
- 使用索引代替迭代器(如果允許)。
2.2 vector 的刪除操作(erase, pop_back)
當從 vector 刪除元素時:
- 被刪除元素的迭代器失效。
- 被刪除元素之后的所有迭代器失效(因為后面的元素會向前移動)。
- 刪除點之前的迭代器仍然有效。
示例:erase 導致迭代器失效
vector<int> v = {1, 2, 3, 4};
auto it = v.begin() + 2; // it 指向 3
v.erase(v.begin() + 1); // 刪除 2
cout << *it; // ? 危險!it 已經(jīng)失效(3 已經(jīng)前移)如何正確刪除?
- 使用
erase的返回值(返回下一個有效迭代器):
vector<int> v = {1, 2, 3, 4};
auto it = v.begin();
while (it != v.end()) {
if (*it % 2 == 0) {
it = v.erase(it); // 刪除并更新 it
} else {
it++; // 否則正常遞增
}
}反向遍歷(避免迭代器失效)
for (auto it = v.rbegin(); it != v.rend(); ) {
if (*it % 2 == 0) {
it = vector<int>::reverse_iterator(v.erase(it.base() - 1));
} else {
it++;
}
}3. 其他容器的迭代器失效情況
| 容器 | 插入操作(insert) | 刪除操作(erase) |
|---|---|---|
vector | 可能失效(取決于容量) | 被刪除及后面的失效 |
deque | 可能失效(首尾安全) | 被刪除及附近的失效 |
list | 不會失效 | 僅被刪除的失效 |
map/set | 不會失效 | 僅被刪除的失效 |
4. 總結
vector插入時:- 可能失效(如果觸發(fā)重新分配)。
- 避免方法:提前
reserve()或使用索引。
vector刪除時:- 被刪除及后面的迭代器失效。
- 正確做法:使用
erase返回值或反向遍歷。
- 其他容器(如
list、map)通常更安全,但仍需謹慎。
最佳實踐:
- 避免在遍歷時直接修改容器,除非明確知道迭代器是否有效。
- 盡量使用
range-based for或算法(如remove_if),減少手動管理迭代器。 - 調(diào)試時使用
-D_GLIBCXX_DEBUG(GCC)檢測迭代器錯誤。
以上就是C++迭代器失效的避坑指南的詳細內(nèi)容,更多關于C++迭代器失效的資料請關注腳本之家其它相關文章!
相關文章
C++實現(xiàn)LeetCode(30.串聯(lián)所有單詞的子串)
這篇文章主要介紹了C++實現(xiàn)LeetCode(30.串聯(lián)所有單詞的子串),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07
詳解C++?OpenCV實現(xiàn)圖像拼接的原理及方法
本文以實現(xiàn)圖像拼接為目標,把分割開的圖像進行拼接還原,核心的內(nèi)容包括:OpenCV圖像拼接相關原理以及OpenCV圖像拼接案例的實現(xiàn),感興趣的可以了解一下2022-07-07
C語言數(shù)組實現(xiàn)學生信息管理系統(tǒng)設計
這篇文章主要為大家詳細介紹了C語言數(shù)組實現(xiàn)學生信息管理系統(tǒng)設計,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01

