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
相关产品推荐
相关产品推荐

