scanf读取name后num_of_rooms值随机变化的问题求助
问题根源与修复方案
核心问题:内存越界写入破坏栈变量
num_of_rooms值变成随机数的直接原因是内存越界写入:
- 在
case 'D'分支中,你定义了单个字符变量char name;,但用scanf("%s", &name);读取输入。%s格式符用于读取字符串,会把输入的所有字符加上自动补的字符串终止符\0写入目标地址。 - 单个
char只有1字节存储空间,输入任何长度≥1的名字时,scanf都会向&name地址写入超过1字节的数据,直接覆盖栈上相邻内存。而num_of_rooms作为栈变量刚好在name附近,因此被破坏成随机值。
其他关键问题与修复
1. 名字存储类型错误
Person结构体里的name定义为char name;,只能存单个字符,根本没法存储完整名字。改成字符数组或者动态字符串指针:
typedef struct Person { char name[20]; // 固定长度数组,或用char* name;后续动态分配 int number_of_keys; }Person;
读取名字时要限制长度防止越界:scanf("%19s", people[num_of_people - 1].name);
2. realloc未更新主函数指针
change_num_of_people函数里,realloc的结果赋值给了局部变量_people,主函数的people指针完全没变化,会导致原指针失效、内存泄漏。改法二选一:
- 返回新指针:
Person* change_num_of_people(Person* _people, int _num_of_people) { return realloc(_people, _num_of_people * sizeof(Person)); } // 主函数调用时更新指针 people = change_num_of_people(people, num_of_people);
- 传递指针的指针:
void change_num_of_people(Person** _people, int _num_of_people) { *_people = realloc(*_people, _num_of_people * sizeof(Person)); } // 主函数调用 change_num_of_people(&people, num_of_people);
3. output函数格式符错误
output里用%s打印(_rooms + i)->key_holder->name,原name是char类型,应该用%c;改成字符数组后再用%s:
// 原char name时用%c printf("%c %i ", (_rooms + i)->key_holder->name, (_rooms + i)->key_holder->number_of_keys); // 改为char name[20]后用%s printf("%s %i ", (_rooms + i)->key_holder->name, (_rooms + i)->key_holder->number_of_keys);
4. 初始malloc的未定义行为
num_of_people=0时,malloc(0)的行为是未定义的,建议初始化为NULL,第一次扩容时再分配:
Person* people = NULL;
realloc(NULL, size)等价于malloc(size),不影响后续逻辑。
修复后的关键代码片段示例
修改Person结构体和case 'D'分支:
typedef struct Person { char name[20]; int number_of_keys; }Person; // ... case 'D': { char input_name[20]; int room_index; printf("number of rooms = %i\n", num_of_rooms); scanf("%19s", input_name); printf("number of rooms = %i\n", num_of_rooms); scanf("%i", &room_index); num_of_people++; people = change_num_of_people(people, num_of_people); strcpy(people[num_of_people - 1].name, input_name); people[num_of_people - 1].number_of_keys = 1; // ... 后续逻辑 break; }
内容的提问来源于stack exchange,提问作者Binio
相关产品推荐
相关产品推荐

