迭代器失效问题简析
迭代器失效(Iterator Invalidation)是指:在容器发生修改后,原有迭代器不再指向合法、有效的元素位置 。继续使用失效的迭代器会导致未定义行为(UB),即使程序看似"正常运行"。
为什么失效?
迭代器失效不等于指针悬空。它本质是语义失效------迭代器所代表的逻辑位置已不存在,原因包括:
- 元素被删除或移动(如
vector::erase) - 容器重新分配内存(如
vector扩容) - 哈希表 rehash(如
unordered_map::insert)
✅ 注意:即使底层内存未释放,迭代器也可能失效!
常见容器行为
常见容器的迭代器失效规则
| 容器 | 插入导致失效 | 删除导致失效 |
|---|---|---|
vector |
扩容:全部失效;否则:插入点及之后失效 | 删除点及之后失效 |
string |
同 vector(因实现为连续字符数组) |
同 vector |
deque |
通常所有迭代器失效 | 通常所有迭代器失效 |
list / forward_list |
无失效(除被删/插位置自身) | 仅被删元素的迭代器失效 |
map / set |
无失效 | 仅被删元素的迭代器失效 |
unordered_* |
rehash 时全部失效 | 仅被删元素的迭代器失效 |
安全示例
cpp
// 正确:使用 erase 返回值
for (auto it = vec.begin(); it != vec.end(); ) {
if (*it % 2 == 0)
it = vec.erase(it); // it 被更新为下一个有效位置
else
++it;
}
关键原则
不要在修改容器后继续使用旧迭代器(除非确认安全,如 list)。 erase 后务必使用其返回值,而非原迭代器。
理解你所用容器的失效规则,比依赖"看起来能跑"更可靠。