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

C语言中如何在子函数中填充动态数组并在main函数中释放内存

动态数组填充函数的内存错误分析与修正

你遇到的Valgrind错误本质上是C语言值传递特性导致的典型问题——你在initialize函数里对数组指针的修改根本没同步到main里的原指针,这直接引发了无效释放和内存泄漏。

为什么原代码会出错?

当你在main中调用initialize(arr)时,传递的是arr指针的副本:

  • initialize函数里的arr是局部变量,和main里的arr完全是两个不同的变量,只是一开始指向同一块内存。
  • 每次调用realloc时,可能会返回新的内存地址(旧内存块会被自动释放),但这个新地址只会存在于initialize的局部arr中,main里的原arr始终指向最初malloc的那块已经被释放的内存。
  • 函数结束后,initialize的局部arr被销毁,realloc分配的新内存地址彻底丢失(内存泄漏);而main里执行free(arr)时,释放的是已经被realloc回收的旧内存块,这就触发了"Invalid free()"错误。

两种可行的修正方案

方案一:使用二级指针(指针的指针)

通过传递指针的地址,让函数能直接修改main里的原指针:

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

void initialize(int** arr) {
    char sign;
    int i = 0;
    do {
        // 解引用二级指针,访问原数组的元素
        scanf("%d%c", &(*arr)[i], &sign);
        i++;
        // 重新分配内存,并更新原指针的指向
        *arr = realloc(*arr, sizeof(int) * (i + 1));
        // 生产代码一定要检查内存分配是否成功
        if (*arr == NULL) {
            fprintf(stderr, "内存分配失败\n");
            exit(EXIT_FAILURE);
        }
    } while (sign != '\n');
}

int main() {
    int* arr = malloc(sizeof(int));
    if (arr == NULL) {
        fprintf(stderr, "内存分配失败\n");
        return EXIT_FAILURE;
    }
    // 传递指针的地址给initialize
    initialize(&arr);
    
    // 这里可以添加数组的使用逻辑,比如遍历打印
    // ...
    
    free(arr);
    return EXIT_SUCCESS;
}

方案二:让函数返回更新后的指针

另一种更直观的方式是让initialize函数返回重新分配后的指针,main直接接收新地址:

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

int* initialize(int* arr) {
    char sign;
    int i = 0;
    do {
        scanf("%d%c", &arr[i], &sign);
        i++;
        arr = realloc(arr, sizeof(int) * (i + 1));
        if (arr == NULL) {
            fprintf(stderr, "内存分配失败\n");
            exit(EXIT_FAILURE);
        }
    } while (sign != '\n');
    // 返回最新的数组指针
    return arr;
}

int main() {
    int* arr = malloc(sizeof(int));
    if (arr == NULL) {
        fprintf(stderr, "内存分配失败\n");
        return EXIT_FAILURE;
    }
    // 接收函数返回的新指针
    arr = initialize(arr);
    
    // 使用数组...
    
    free(arr);
    return EXIT_SUCCESS;
}

额外注意事项

  • 务必检查malloc和realloc的返回值,空指针访问会导致程序崩溃。
  • 原输入逻辑scanf("%d%c")存在小问题:如果用户用空格分隔数字,sign会读取到空格而非换行,循环无法终止。可以改成先读取数字,再用getchar()清理输入缓冲区的空格/换行,或者调整格式控制符。
  • 你的循环最后会多分配一个int的空间(因为i+1),如果不需要这个额外空间,可以在循环结束后调用realloc(arr, sizeof(int)*i)来调整大小。

内容的提问来源于stack exchange,提问作者Катя Павліченко

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:42:41