C++ vector循环去重异常:为何必须添加break语句才能得到正确结果?
移除vector重复元素时必须添加break的原因
问题描述
我在移除vector<int>中的重复整数时,发现编写的嵌套循环只有在if判断内添加break;才能正常工作,否则会输出错误结果。相关代码如下:
#include<iostream> #include<vector> using namespace std; vector<int> nums = {3, 4, 4, 4, 3, 3, 6, 6, 3}; int main() { for(int i = nums.size() - 1 ; i >= 0 ; i--) { for( int z = i - 1; z >= 0; z--) { if( nums[i] == nums[z] ) { nums.erase(nums.begin() + i); break; // 去掉这行结果就出错 } } } for( int c : nums) { cout << c << " "; } }
原因解释
- 越界访问触发未定义行为:执行
erase后,vector的长度会直接减1。此时原来的索引i已经超出了当前vector的有效索引范围(比如初始size为9,删除索引8的元素后,最大有效索引变为7,但i还是8)。如果不中断内层循环,后续代码会继续访问nums[i],这属于非法内存访问,会导致输出结果混乱甚至程序崩溃。 - 重复删除无效索引:即使没触发越界,内层循环继续执行的话,可能会再次进入if判断,尝试删除已经不存在的索引
i(第一次erase后该位置元素已被移除),破坏vector的内部结构。 - 逻辑上无需继续比较:只要找到当前元素在前面有重复,就已经完成了该元素的去重操作,没必要再和更前面的元素对比。
break可以终止内层循环,避免冗余操作,同时从根源上防止后续的错误访问。
内容的提问来源于stack exchange,提问作者Maamar Darmech
相关产品推荐
相关产品推荐

