正确删除vector元素须用erase配合迭代器,如v.erase(v.begin()+i);批量删除应采用remove_if+erase组合,避免下标操作导致越界或漏删,且需注意erase后迭代器失效及手动shrink_to_fit释放内存。

用 erase 删除单个或连续元素,别直接用下标删
直接写 v[i] = v.back(); v.pop_back(); 这类操作会破坏顺序、漏删、甚至越界——vector 不是哈希表,删除中间元素必须靠 erase 移动后续数据。正确做法是传入迭代器:v.erase(v.begin() + i) 删第 i 个,或 v.erase(it) 删指定位置的迭代器。
注意:erase 返回被删元素后一个位置的迭代器(C++11 起),所以循环中边删边遍历时不能简单 i++,否则跳过下一个元素。
- 删所有偶数:用
remove_if+erase组合(见下节) - 删第 0 个:用
v.erase(v.begin()),不是v.erase(0)(编译不过) - 删最后一个:优先用
v.pop_back(),比v.erase(--v.end())快且语义清晰
remove_if + erase 是删多个元素的标准套路
remove_if 不真删,只是把要保留的元素往前挪,返回新逻辑尾部的迭代器;再用 erase 一次性抹掉后面那段“脏数据”。这是唯一高效、安全、符合 STL 习惯的批量删除方式。
例如删掉所有值为 0 的元素:
立即学习“C++免费学习笔记(深入)”;
vectorv = {1, 0, 2, 0, 3}; v.erase(remove_if(v.begin(), v.end(), [](int x) { return x == 0; }), v.end()); // 结果:{1, 2, 3}
- 不能只调
remove_if就完事——容器大小没变,末尾残留旧值 - lambda 捕获需谨慎:若用
[&]引用外部变量,确保该变量生命周期覆盖整个 erase 过程 - 对
vector等类型,> remove_if会移动指针,不触发析构,安全
循环中删除要小心迭代器失效和越界
正向 for 循环用下标 for (int i = 0; i 删元素时,删完 v[i] 后 v[i+1] 会前移到 i 位置,但 i 还会自增,导致跳过新到的元素。
- 安全做法:反向遍历(
for (int i = v.size()-1; i >= 0; --i)),删不影响前面索引 - 或用迭代器 while 循环:
auto it = v.begin(); while (it != v.end()) { if (need_erase) it = v.erase(it); else ++it; } - 千万别在循环里写
v.erase(v.begin() + i); i++;——erase后v.size()变小,i可能越界
性能与内存:删完不缩容,shrink_to_fit 手动触发
erase 和 remove_if+erase 都只减少 size(),不改变底层分配的容量(capacity())。如果之后不再插入大量元素,这部分内存就浪费了。
- 确认需要释放内存时,加一句
v.shrink_to_fit();(C++11 起),但它是非强制的,实现可忽略 - 频繁增删场景,考虑换用
std::list或std::deque,但注意随机访问性能下降 - 若只是临时过滤,用
vector构造新容器(vector)有时比原地 erase 更快,尤其删除比例高时new_v; new_v.reserve(old_v.size());
erase、忘了 remove_if 必须配 erase、以及以为删完自动缩容。这些地方一错,轻则逻辑错误,重则读到未初始化内存。











