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

LeetCode中C语言findMedianSortedArrays函数的堆缓冲区溢出(Heap Buffer Overflow)问题求助

LeetCode中C语言findMedianSortedArrays函数的堆缓冲区溢出(Heap Buffer Overflow)问题求助

我来帮你分析代码里的问题,以及对应的修复方案:

首先,你的ASAN报错确实是数组越界访问导致的,代码里主要有这几个逻辑漏洞:

1. Flag标记与数组指针的逻辑冲突

你设置的flag1和flag2分支不仅逻辑容易混淆,触发flag后也没限制指针的递增边界:
比如当nums1遍历完(flag1=true),你会持续读取nums2[br2]并执行br2++,但完全没检查br2是否已经超过nums2Size。举个例子:如果nums1是[1,3],nums2是[2,4,5],当nums1遍历完后,br2会从1递增到2(取元素5),下一次循环br2变成3,这时候访问nums2[3]就超出了数组边界(nums2Size是3,最大索引是2),直接触发堆溢出。

2. 未处理空数组的边界情况

如果其中一个输入数组是空的(比如nums1Size=0),代码一开始就会执行nums1[br1](也就是nums1[0]),但空数组没有索引0的元素,直接触发越界报错。

3. 冗余的指针回退操作

当br2 == nums2Size时,你执行br2--完全没必要,这会导致后续重复读取数组最后一个元素,还会加快指针越界的速度。


修复后的代码(简洁且无越界)

我重构了合并数组的逻辑,用更清晰的方式彻底避免越界,同时修复了内存泄漏问题:

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {  
    int total_size = nums1Size + nums2Size;
    // 动态分配合并后的数组
    int* merged_arr = (int*)malloc(sizeof(int) * total_size);
    if (merged_arr == NULL) {
        return 0.0; // 内存分配失败的兜底处理
    }

    int p1 = 0, p2 = 0, idx = 0;

    // 先合并两个数组都有剩余元素的部分
    while (p1 < nums1Size && p2 < nums2Size) {
        if (nums1[p1] <= nums2[p2]) {
            merged_arr[idx++] = nums1[p1++];
        } else {
            merged_arr[idx++] = nums2[p2++];
        }
    }

    // 把nums1剩下的元素全部加入
    while (p1 < nums1Size) {
        merged_arr[idx++] = nums1[p1++];
    }

    // 把nums2剩下的元素全部加入
    while (p2 < nums2Size) {
        merged_arr[idx++] = nums2[p2++];
    }

    // 计算中位数
    double median;
    if (total_size % 2 == 0) {
        median = (merged_arr[total_size/2 - 1] + merged_arr[total_size/2]) / 2.0;
    } else {
        median = merged_arr[total_size/2];
    }

    free(merged_arr); // 释放动态分配的内存,避免泄漏
    return median;
}

修复点说明:

  • 用三个独立的while循环处理合并,每一步都检查指针是否在数组范围内(p1 < nums1Size),彻底杜绝越界。
  • 自然处理空数组情况:如果nums1是空的,第一个循环直接跳过,进入第三个循环处理nums2的所有元素,不会访问空数组。
  • 加上了free(merged_arr),避免内存泄漏(LeetCode可能不卡这个,但养成好习惯很重要)。

更高效的优化方案(不用合并数组)

你的代码是O(m+n)时间复杂度,而这道题的最优解法是O(log(min(m,n)))的二分查找法,不需要合并整个数组:
核心思路是在较短的数组中找分割点,把两个数组分成左右两部分,确保左边所有元素都小于等于右边所有元素,然后直接通过分割点计算中位数,不需要额外的内存空间。如果需要我展开讲这个方法,可以告诉我~

备注:内容来源于stack exchange,提问作者golub001

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:29:33