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

C语言动态数组异常:函数内打印正常,main中输出地址而非值

问题分析

你的问题出在指针的传值传递上:

  • main中声明的numbers是指向动态数组的指针,传递给readNames时,传的是指针的副本(值传递)。
  • 函数内调用realloc时,若内存需要重新分配,会返回新地址,此时修改的是函数内的局部numbers指针,而非main里的原指针。
  • 函数返回后,main的numbers仍指向最初malloc的旧地址,该地址可能已被realloc释放,访问时会得到非法垃圾值,看起来像输出地址。
解决方案

要让realloc的结果同步到main,需要传递指针的指针(即int **numbers),这样函数能直接修改main中指针变量的指向。具体修改步骤:

  1. 调整函数声明和定义,将int *numbers改为int **numbers
  2. 函数内访问数组时,先解引用指针((*numbers)[*total])
  3. 调用realloc时,直接更新*numbers(即main中的原指针)
  4. 若后续启用names字符串数组,需做同样修改
修改后的完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void readNames(FILE *, int **, char ***, int *);

void readNames(FILE *fpN, int **numbers, char ***names, int *total){
    char sentence[512];

    while (fgets(sentence, sizeof(sentence), fpN)){
        char *token = strtok(sentence, " "); // 读取数字部分
        (*numbers)[*total] = atoi(token); // 存入数组
        
        token = strtok(NULL, " \n");
        
        // 若要启用名字存储,取消下面注释并同步修改names的指针传递
        // (*names)[*total] = malloc(strlen(token)+1);
        // strcpy((*names)[*total], token);
        
        (*total)++;

        // 重新分配int数组内存,直接修改main中的指针
        *numbers = realloc(*numbers, (*total + 1) * sizeof(int));
        // 若启用names,同样修改:
        // *names = realloc(*names, (*total + 1) * sizeof(char*));
    }
 
    // 函数内打印验证
    printf("%d ", (*(*numbers + 2)));
    printf("%d ", (*numbers)[1]);
    printf("%d\n", (*numbers)[2]);
}


int main(int argc, char **argv){
    FILE *fpN = NULL;
    FILE *fpG = NULL;

    if(argc!=3){
        printf("参数错误\n");
        exit(0);
    }

    if ((fpN = fopen(argv[1], "r")) == NULL){
        printf("未找到文件!\n");
        exit(0);
    }

    if ((fpG = fopen(argv[2], "r")) == NULL){
        printf("未找到文件!\n");
        exit(0);
    }

    int total = 0;
    int *numbers = malloc(sizeof(int)); // 初始分配1个int的空间
    char **names = malloc(sizeof(char*));

    // 传递指针的地址
    readNames(fpN, &numbers, &names, &total);

    // main中打印验证
    printf("%d ", numbers[0]);
    printf("Enter ");
    printf("%d ", numbers[1]);
    printf("%d ", numbers[2]);
    printf("Enter\n");

    // 释放动态分配的内存,避免泄漏
    free(numbers);
    // 若启用names,还要逐个释放字符串再释放names数组
    // for(int i=0; i<total; i++) free(names[i]);
    // free(names);

    fclose(fpN);
    fclose(fpG);
    return 0;
}
额外注意事项
  • C语言中realloc的返回值无需强制类型转换,void*可隐式转换为其他指针类型
  • 必须在程序结束前释放动态内存,避免内存泄漏
  • 可添加realloc返回值检查,防止内存分配失败(比如if(*numbers == NULL) { /* 错误处理逻辑 */ })

内容的提问来源于stack exchange,提问作者George Pettemeridis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:35:25