嵌套结构体数组为何会覆盖已存储值?
问题原因分析
未初始化的指针
nm
代码中char *nm;仅声明了指针,但未分配任何内存空间,也未指向有效的内存区域。调用fgets(nm, 30, stdin)时,属于访问未定义内存,行为完全不可控——可能直接程序崩溃,也可能数据被写入随机区域,导致后续无法正确读取。所有投票者的
name指向同一块内存(即使nm初始化)
就算给nm分配了固定内存,每次输入都复用同一个缓冲区,再把这个指针赋值给不同的voterDetails[i].name,所有结构体的name字段都会指向同一块内存。新输入的名字会直接覆盖旧内容,导致之前存储的名字被冲掉,看起来像是没保留。scanf残留换行符导致输入异常scanf("%d", &choice)读取整数后,输入缓冲区会残留一个换行符。第一个fgets会直接读取这个换行符,得到空字符串,第二个fgets才是实际输入的名字。这会导致第一次存储的内容不符合预期,甚至出现空值。
修复方案
为每个投票者的
name单独分配内存
不要复用同一个缓冲区,而是每次输入后为对应投票者的name字段分配独立内存并复制字符串,避免覆盖:// 替换原char *nm;为临时缓冲区 char tempName[30]; // 输入名字 fgets(tempName, 30, stdin); // 去除fgets读入的换行符 tempName[strcspn(tempName, "\n")] = '\0'; // 分配内存并复制字符串 temp->voterDetails[voteNum-1].name = malloc(strlen(tempName) + 1); strcpy(temp->voterDetails[voteNum-1].name, tempName);处理
scanf后的残留换行符
在scanf读取选择后,用getchar()丢弃缓冲区里的换行符,这样后续的fgets就能直接读取输入的名字,不需要两次调用:scanf("%d", &choice); getchar(); // 吃掉换行符添加数组越界检查
每次投票前检查voteNum是否已达到5(voterDetails的最大容量),避免非法访问内存:case 1: if(voteNum >=5){ printf("当前区块已无剩余投票名额\n"); break; } // 后续输入逻辑
内容的提问来源于stack exchange,提问作者Syed Muhammad Taha
相关产品推荐
相关产品推荐

