You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:25:58