C语言中char数组指针失效导致乱码问题求助
问题原因与修复方案
问题原因
你的猜测完全正确:addNames()函数中的name是栈上的局部字符数组,函数执行完毕返回main时,对应的栈帧会被销毁,这块内存会被操作系统回收或后续代码覆盖。而names数组中保存的所有指针,都指向了这块已经失效的内存区域,因此在main中打印时会出现乱码。
修复方案
以下是三种可行的修复方式,可根据场景选择:
方案1:使用静态二维数组存储
将局部数组改为静态存储,静态变量存放在全局数据区,函数退出后不会被销毁。为每个名字分配独立的静态存储空间,避免覆盖:
#include <stdio.h> #include <string.h> #define MAX_NAMES 5 #define MAX_NAME_LENGTH 20 char* names[MAX_NAMES]; void addNames(); int main(){ addNames(); printf("\n"); for(int i=0; i<MAX_NAMES; i++){ printf("Name from array #%d: %s\n", i+1, names[i]); } return 0; } void addNames(){ // 静态二维数组,为每个名字分配独立空间 static char name_storage[MAX_NAMES][MAX_NAME_LENGTH]; for(int i=0; i<MAX_NAMES; i++){ printf("Give me the name #%d: ", i+1); fgets(name_storage[i], MAX_NAME_LENGTH, stdin); name_storage[i][strlen(name_storage[i])-1]='\0'; names[i] = name_storage[i]; printf("Name given: %s\n", names[i]); } }
方案2:动态分配堆内存(推荐)
使用malloc为每个名字单独分配堆内存,堆内存不会随函数退出自动释放,需手动调用free避免内存泄漏:
#include <stdio.h> #include <string.h> #include <stdlib.h> // 引入malloc/free所需头文件 #define MAX_NAMES 5 #define MAX_NAME_LENGTH 20 char* names[MAX_NAMES]; void addNames(); int main(){ addNames(); printf("\n"); for(int i=0; i<MAX_NAMES; i++){ printf("Name from array #%d: %s\n", i+1, names[i]); } // 释放堆内存,避免泄漏 for(int i=0; i<MAX_NAMES; i++){ free(names[i]); } return 0; } void addNames(){ char name[MAX_NAME_LENGTH]; for(int i=0; i<MAX_NAMES; i++){ printf("Give me the name #%d: ", i+1); fgets(name, MAX_NAME_LENGTH, stdin); name[strlen(name)-1]='\0'; // 分配足够内存(+1用于存储字符串终止符'\0') names[i] = malloc(strlen(name) + 1); if(names[i] == NULL){ // 检查内存分配是否成功 perror("malloc failed"); exit(EXIT_FAILURE); } strcpy(names[i], name); printf("Name given: %s\n", names[i]); } }
方案3:直接使用全局二维数组
将全局的指针数组改为二维字符数组,直接存储字符串,彻底避免指针失效问题:
#include <stdio.h> #include <string.h> #define MAX_NAMES 5 #define MAX_NAME_LENGTH 20 // 全局二维数组,直接存储每个名字 char names[MAX_NAMES][MAX_NAME_LENGTH]; void addNames(); int main(){ addNames(); printf("\n"); for(int i=0; i<MAX_NAMES; i++){ printf("Name from array #%d: %s\n", i+1, names[i]); } return 0; } void addNames(){ for(int i=0; i<MAX_NAMES; i++){ printf("Give me the name #%d: ", i+1); fgets(names[i], MAX_NAME_LENGTH, stdin); names[i][strlen(names[i])-1]='\0'; printf("Name given: %s\n", names[i]); } }
内容的提问来源于stack exchange,提问作者moyoloco09
相关产品推荐
相关产品推荐

