这是我的代码
char c[3];
gets(c);
puts(c);
这里char变量c有3个索引。但如果我输入超过3个字母,那么我的代码打印超过3个字母,我打字。 但是怎么可能c一次只能存储3个字符。不是吗?
答案 0 :(得分:5)
来自gets
的说明:
在给定足够长的输入字符串的情况下,该函数无法防止目标数组的缓冲区溢出。
因此,如果stdin
碰巧有超过3个字符,那么您的代码就是未定义的行为。这是一个更喜欢打电话的好理由:
fgets(c, sizeof(c), stdin);
绝对不会溢出。
答案 1 :(得分:3)
欢迎来到buffer overflows的精彩世界。
数组上没有长度检查,因此代码从数组的末尾走开并继续写入相邻的内存。这是代码中安全问题的众多原因之一。
答案 2 :(得分:2)
gets()
不限制要读取的字符数,它不关心它们写入的位置,它假定目标缓冲区足够大。
为什么你会期望它停止阅读?
正因为如此,您应该使用differet函数来限制要读取的字符数,您需要fgets()
char c[3];
fgets(c, sizeof(c), stdin);
puts(c);
这将毫无问题地工作,但请注意,实际上只会读取2个字符,因为第3个位置是为终止'\0'
字节保存的,这会使您的数组成为字符串。
您的程序正在调用未定义的行为,因此您可能会观察到奇怪的结果或者您的程序可以正常工作,它不依赖于程序本身,而是依赖于其他事情,例如输入和其他事情。
答案 3 :(得分:1)
您有责任确保缓冲区足够大以容纳gets()
读取的整个字符串(包括终止空值)。如果未能这样做,则会发生未定义的行为(实际上这意味着其他内存位置会被覆盖)。除非您对输入字符串的长度有所保证,否则通常无法安全地完成此操作。这就是为什么在C99和C ++ 11中不推荐使用gets
并在C11和C ++ 14中删除它。请考虑改为使用fgets
。
答案 4 :(得分:0)
gets()
实际上并不知道传递给它的内存块有多大。如果你给它更多的字符大于块大小,你就会调用未定义的行为。