C语言猜数字游戏:结构体player_name重启后丢失问题求助
问题排查与解决方案
核心问题:野指针导致字符串丢失
你的代码中player_name字符串丢失的根本原因是局部变量内存释放后形成野指针:
在Player_Infos函数里,char new_name[80]是栈上的局部数组,当函数执行完毕返回时,这块栈内存会被系统回收复用。而你把player_p->player_name指向了这个局部数组的地址,后续访问这个指针时,内存内容已经被覆盖,就会出现字符串丢失、乱码等问题。
而player_score是int类型,直接赋值的是值而非指针,不受局部变量内存回收影响,因此能正常保留。
修复方案
以下两种方案任选其一即可:
方案1:结构体中使用固定大小字符数组
修改结构体定义,直接在结构体里分配足够的字符空间存储用户名,避免使用指针:
typedef struct { int player_score; char player_name[80]; // 替换char*为固定大小数组 } HS_Player;
然后修改Player_Infos函数的赋值逻辑,用strcpy拷贝字符串:
void Player_Infos(HS_Player *player_p, int score) { char new_name[80]; printf("Congrats! Your made a new high score.\n"); printf("What's your name ?\t"); scanf("%s", new_name); printf("\n"); player_p->player_score = score; strcpy(player_p->player_name, new_name); // 用strcpy拷贝字符串到结构体数组 }
注意:需添加头文件#include <string.h>以使用strcpy函数。
方案2:动态分配内存存储用户名
如果不想限制用户名长度,可使用malloc动态分配内存,记得在程序结束前用free释放(避免内存泄漏):
修改Player_Infos函数:
void Player_Infos(HS_Player *player_p, int score) { char new_name[80]; printf("Congrats! Your made a new high score.\n"); printf("What's your name ?\t"); scanf("%s", new_name); printf("\n"); player_p->player_score = score; // 先释放之前的内存(若存在),避免内存泄漏 if (player_p->player_name != NULL) { free(player_p->player_name); } // 分配足够内存存储字符串(+1用于存储结束符'\0') player_p->player_name = malloc(strlen(new_name) + 1); if (player_p->player_name != NULL) { strcpy(player_p->player_name, new_name); } }
同时在main函数结束前添加释放逻辑:
int main(void) { // ... 原有代码 ... // 程序结束前释放动态分配的内存 free(player.player_name); return EXIT_SUCCESS; }
同样需要添加#include <string.h>头文件。
额外优化建议
Random_Value函数中,srand(time(NULL))应仅调用一次,放在main函数开头即可,否则每次调用Random_Value都会重新初始化随机数生成器,可能导致生成的随机数重复。Get_User_Choice函数中,递归调用时需添加返回值,改为return Get_User_Choice();,否则可能返回错误值。
内容的提问来源于stack exchange,提问作者Jérôme Vdb
相关产品推荐
相关产品推荐

