erase 是 vector 唯一能真正释放内存中已删除元素位置的成员函数,但它不自动缩容——删完后 capacity() 不变,只有 size() 减少。
删除单个元素用迭代器:
std::vectorv = {1, 2, 3, 4, 5}; auto it = v.begin() + 2; // 指向 3 v.erase(it); // v 变为 {1, 2, 4, 5}
删除区间用两个迭代器:
v.erase(v.begin() + 1, v.begin() + 3); // 删除下标 1~2(含头不含尾),即 2 和 4 → {1, 5}
v.erase(v.end()) 是未定义行为erase 时不能直接 i++
erase 效率低(每次都要移动后续元素)想删掉所有值为 3 的元素?别写 for (auto it = v.begin(); it != v.end(); ++it) 加 erase —— 迭代器失效会导致跳过元素或崩溃。
立即学习“C++免费学习笔记(深入)”;
正确做法是用 std::remove 配合 erase:
std::vectorv = {1, 3, 2, 3, 4, 3}; v.erase(std::remove(v.begin(), v.end(), 3), v.end()); // v 变为 {1, 2, 4}
std::remove 不真删,只是把要保留的元素前移,返回新逻辑结尾的迭代器erase 接收该迭代器和 v.end(),一次性擦除“冗余尾部”std::remove_if 替代,传入 lambda 或谓词vector 没有 erase(int index) 重载,必须转成迭代器。常见错误是越界没检查:
v.erase(i) —— 编译不过,erase 只接受迭代器v.erase(v.begin() + i) —— 若 i >= v.size(),结果未定义if (i >= 0 && i < static_cast(v.size())) { v.erase(v.begin() + i); }
注意 size() 返回 size_t,与有符号 int 比较时可能隐式转换出问题,显式转成 size_t 或用
static_cast 更稳妥。
erase 后 v.capacity() 不变,哪怕删光了所有元素,内存还在。如果确定后续不再增容,且在意内存占用,得主动调用:
v.erase(v.begin(), v.end()); v.shrink_to_fit(); // C++11 起支持,请求系统回收多余容量
shrink_to_fit 是“请求”,不是强制;实现可忽略(比如 libstdc++ 通常响应,MSVC 早期版本可能不)clear() 只改 size,不缩容真正难处理的是嵌套循环里删多个位置、或删除依据是运行时计算结果的情况——这时候别硬套 erase,先收集待删索引再倒序删,或者换用其他容器如 list(但要权衡随机访问代价)。