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

C语言内存分配错误排查:动态分配后第二堆输出全为0的问题

问题定位与修复方案

嘿,一眼就揪出问题所在了——动态分配数组b的赋值循环存在严重的索引越界错误,这直接导致第二堆输出全是无效的0值。

问题根源分析

当你用malloc为b分配pq_2_size(比如M=10时是5)个元素的空间时,b的有效索引范围是0到pq_2_size-1(也就是0到4)。但你的赋值循环是这么写的:

for (int j = pq_1_size; j < M; j++) {
    b[j] = j;
}

当M=10时,j从5遍历到9,直接用j作为b的索引,相当于访问b[5]、b[6]...这些完全超出b内存范围的位置!这种越界访问会破坏内存结构:不仅没给b的有效位置赋值,还可能干扰其他变量的存储,最终导致buildHeap读取b时拿到的都是未初始化的垃圾值(表现为全0)。

而静态数组能正常运行,是因为你直接给b[0]到b[4]赋值了5到9,完全符合数组的索引范围。

修复后的代码

只需要修改b的赋值循环,把j转换成b的相对索引即可:

int main(int argc, char *argv[]) {
    int M = atoi(argv[1]);
    int pq_1_size = M / 2;
    int pq_2_size = M - pq_1_size;
    int *a;
    int *b;
    a = (int *)malloc(pq_1_size * sizeof(int));
    b = (int *)malloc(pq_2_size * sizeof(int));

    // 给数组a正确赋值
    for (int i = 0; i < pq_1_size; i++) {
        a[i] = i;
    }

    // 修复:将j转换为b的相对索引(j - pq_1_size)
    for (int j = pq_1_size; j < M; j++) {
        b[j - pq_1_size] = j;
    }

    Heap someHeap = { 0, {0} };
    Heap *A = &someHeap;
    buildHeap(A, a, pq_1_size);
    print(A);
    printf("\n");

    Heap anotherHeap = { 0, {0} };
    Heap *B = &anotherHeap;
    buildHeap(B, b, pq_2_size);
    print(B);

    // 主动释放动态分配的内存,避免泄漏
    free(a);
    free(b);

    return 0;
}

额外小建议

  • 养成动态分配内存后主动释放的习惯,虽然程序结束后系统会回收内存,但在大型程序中内存泄漏会导致严重问题。
  • 可以在malloc后添加空指针检查,避免内存分配失败导致的崩溃:
    if (a == NULL || b == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }
    

内容的提问来源于stack exchange,提问作者Utku Kalkanlı

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:52:03