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

移除printf()引发malloc堆损坏:归并排序代码异常求助

问题分析与解决

你的代码存在内存越界破坏堆结构的致命问题,printf("something\n");的存在只是通过改变内存布局暂时掩盖了错误,注释后错误直接暴露。以下是具体原因和修复方案:

核心错误点

1. 归并排序分治拆分完全错误

你当前用(n+1)>>2计算左半数组长度,这是把数组拆成4份,而非归并排序需要的对半拆分。正确的拆分逻辑应该是:

  • 左半部分长度:(n+1)>>1(等价于向上取整n/2)
  • 右半部分长度:n - mit(而非n>>2)

错误的拆分导致左右子数组长度之和远小于原数组长度,递归过程和合并逻辑全部混乱,直接引发后续内存访问越界。

2. 合并循环的越界访问

合并阶段的while(i < mit || j < fin)循环存在严重问题:当其中一个子数组遍历完成后(比如i >= mit),代码仍会执行arr[i] <= mit_arr[j]的判断,此时访问的arr[i]已经超出左半数组的合法范围;同理j >= fin时访问mit_arr[j]也会越界。

这种越界访问会写入不属于当前数组的内存区域,破坏glibc堆管理的元数据。堆元数据被破坏后,后续的malloc/free操作就会触发检测机制,抛出malloc(): corrupted top size错误。

为什么注释printf会触发错误?

printf内部会调用malloc分配输出缓冲区,它会改变程序的堆内存布局。当保留printf时,你的越界访问刚好没有破坏堆顶的关键元数据,错误被暂时隐藏;注释掉后,堆布局发生变化,越界访问直接篡改了堆顶块的结构,触发glibc的堆检测终止信号。

修正后的代码片段

#include <stdio.h>
#include <stdlib.h>

typedef int elem;

void mergesort(elem * arr, unsigned n){
    if(n <= 1){
        return;
    }
    // 正确的对半拆分
    unsigned mit = (n + 1) >> 1;
    unsigned fin = n - mit;
    elem * mit_arr = arr + mit;
    elem * arr_2 = (elem *)malloc(sizeof(elem) * n);
    
    mergesort(arr, mit);
    mergesort(mit_arr, fin);
    
    unsigned i = 0, j = 0, k = 0;
    // 合并两个有序数组,避免越界
    while(i < mit && j < fin){
        if(arr[i] <= mit_arr[j]){
            arr_2[k++] = arr[i++];
        }else{
            arr_2[k++] = mit_arr[j++];
        }
    }
    // 处理左半剩余元素
    while(i < mit){
        arr_2[k++] = arr[i++];
    }
    // 处理右半剩余元素
    while(j < fin){
        arr_2[k++] = mit_arr[j++];
    }
    
    for(unsigned idx=0; idx<n; idx++)
        arr[idx] = arr_2[idx];
    free(arr_2);
}

int main(){
    unsigned a = 10;
    int i;
    elem * arr = (elem*)malloc(sizeof(elem) * a);
    arr[0] = 12;
    arr[1] = 3;
    arr[2] = -3;
    arr[3] = 22;
    arr[4] = 12;
    arr[5] = 11;
    arr[6] = 4;
    arr[7] = 9;
    arr[8] = 10;
    arr[9] = 2;
    
    mergesort(arr, a);
    
    printf("\n");
    for(i=0; i<a; i++){
        printf("%d, ", arr[i]);
    }
    printf("\n");
    free(arr);
    return 0;
}

内容的提问来源于stack exchange,提问作者Mr.Barbo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 12:15:31