LeetCode数组去重代码出现Heap Buffer overflow错误的排查与解决
错误成因分析
1. 堆缓冲区溢出(Heap Buffer overflow)直接原因:数组越界访问
你的代码里有两处明显的越界问题:
- 外层循环中,当
i遍历到numsSize-1时,*(nums+i+1)等价于访问nums[numsSize],但数组的合法下标范围是0到numsSize-1,这时候你读写了不属于当前数组的堆内存区域,直接触发Heap Buffer overflow。 - 内层循环里,
j的循环条件是j < numsSize,当j等于numsSize-1时,*(nums+j+1)同样访问了nums[numsSize],再次造成越界。
2. 额外逻辑问题
除了越界,你的代码逻辑也不符合LeetCode该题的要求:
- 你用
k统计的是重复元素的种类数,但题目要求返回去重后的数组长度。 - 用逐个交换的方式移动重复元素,时间复杂度是O(n²),效率极低,而且每次交换后还要
i--,容易导致循环混乱。
解决方法:双指针法(标准高效解法)
双指针法是数组去重的最优解,时间复杂度O(n),空间复杂度O(1),完全避免越界问题:
int removeDuplicates(int* nums, int numsSize) { // 空数组直接返回0 if (numsSize == 0) return 0; // 慢指针,指向去重后数组的最后一个元素 int slow = 0; // 快指针遍历整个数组 for (int fast = 1; fast < numsSize; fast++) { // 找到和慢指针位置不同的元素 if (nums[fast] != nums[slow]) { // 慢指针前进一位 slow++; // 将新元素放到慢指针位置 nums[slow] = nums[fast]; } } // 去重后的长度是慢指针下标+1 return slow + 1; }
代码逻辑说明
slow指针始终指向去重后数组的最后一个有效元素,初始在第0位。fast指针遍历数组,每找到一个和slow位置不同的元素,就把它复制到slow的下一位,然后slow前进。- 最后返回
slow + 1,因为下标从0开始,长度是下标加1。
这种方法完全不会越界,因为fast的范围是1到numsSize-1,所有数组访问都是合法的,同时高效完成去重和长度统计。
内容的提问来源于stack exchange,提问作者Harshit Kumar
相关产品推荐
相关产品推荐

