C++中for循环遍历删除元素的while等效版本报错问题
vector erase while循环触发AddressSanitizer negative-size-param错误分析
问题背景
- 基于for循环实现的
removeOdd函数,遍历vector<int>并删除奇数元素,编译运行后正常输出Passed - 改写为while循环版本
removeOdd_new后,相同编译参数下运行触发AddressSanitizer的negative-size-param错误 - 已知
std::vector::erase()返回指向被删元素下一个位置的迭代器,但无法定位问题
错误信息解读
negative-size-param错误是AddressSanitizer检测到内存操作传入了负数大小参数的典型提示,在vector erase场景下,本质是代码使用了失效的迭代器,导致容器内部计算内存块范围时出现负数。
问题根源剖析
最常见的错误是在while循环中错误地手动递增迭代器,忽略了erase对迭代器有效性的影响,典型错误写法如下:
void removeOdd_new(vector<int>& nums) { auto it = nums.begin(); while (it != nums.end()) { if (*it % 2 != 0) { nums.erase(it); // erase后it立即失效 } ++it; // 对失效迭代器执行递增,导致越界 } }
当调用erase(it)时,vector会移动后续元素填补被删除的位置,原it指向的内存已被销毁,迭代器直接失效。此时执行++it会让迭代器指向容器内存的非法区域,后续容器的内部操作会基于这个非法迭代器计算内存范围,最终出现负数大小参数,触发报错。
正确的实现应该利用erase返回的迭代器更新当前迭代器,仅在不删除元素时手动递增:
void removeOdd_new(vector<int>& nums) { auto it = nums.begin(); while (it != nums.end()) { if (*it % 2 != 0) { it = nums.erase(it); // 用返回的有效迭代器更新it } else { ++it; // 仅未删除元素时递增迭代器 } } }
内容的提问来源于stack exchange,提问作者Teong Seng Tan
相关产品推荐
相关产品推荐

