为什么C语言中能输入超过已创建结构体数组容量的数据?
问题原因解答
- 核心原因是数组越界访问触发C语言未定义行为:C语言本身不会做数组下标越界检查,你定义的
struct Student s[1]是长度为1的数组,仅s[0]是合法可访问的元素,循环中访问s[1]、s[2]属于典型的越界操作,这种行为的结果没有标准约束,程序没有直接崩溃、数据能临时写入都属于随机的巧合。 - 第二个学生姓名显示为笑脸是越界写入覆盖内存导致的:越界访问时,你写入的内容会覆盖栈空间上数组相邻的其他内存(可能是循环变量
i的存储空间,也可能是其他栈帧数据),在你输入第三个学生信息时,刚好把第二个学生name字段的首字节覆盖成了ASCII码为1的控制字符,这个控制字符在控制台输出时就会渲染为笑脸符号☺。 - 代码中还存在其他不规范的错误用法:
fflush(stdin)属于未定义行为:C标准仅规定fflush对输出流有效,对输入流stdin使用fflush没有统一的行为定义,可移植性极差,清空输入缓冲区建议用循环读取剩余字符的方式实现。gets函数已经被C标准正式废弃:gets完全不检查输入字符串的长度,只要输入内容超过缓冲区大小就会触发溢出漏洞,建议替换为fgets。
修复建议
如果需要存储3个学生的信息,直接将数组定义修改为struct Student s[3]即可;如果需要动态调整存储容量,可使用malloc/realloc动态分配内存空间。
内容的提问来源于stack exchange,提问作者Achellis16
相关产品推荐
相关产品推荐

