C语言动态数组异常:函数内打印正常,main中输出地址而非值
问题分析
你的问题出在指针的传值传递上:
main中声明的numbers是指向动态数组的指针,传递给readNames时,传的是指针的副本(值传递)。- 函数内调用
realloc时,若内存需要重新分配,会返回新地址,此时修改的是函数内的局部numbers指针,而非main里的原指针。 - 函数返回后,
main的numbers仍指向最初malloc的旧地址,该地址可能已被realloc释放,访问时会得到非法垃圾值,看起来像输出地址。
解决方案
要让realloc的结果同步到main,需要传递指针的指针(即int **numbers),这样函数能直接修改main中指针变量的指向。具体修改步骤:
- 调整函数声明和定义,将
int *numbers改为int **numbers - 函数内访问数组时,先解引用指针(
(*numbers)[*total]) - 调用
realloc时,直接更新*numbers(即main中的原指针) - 若后续启用
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
相关产品推荐
相关产品推荐

