以下代码从stdin
读取最多10个字符并输出字符
当我输入超过10个字符时,我预计它会崩溃,因为msg
没有足够的空间,但事实并非如此!怎么会这样?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
char* msg = malloc(sizeof(char)*10);
if (NULL==msg)
exit(EXIT_FAILURE);
scanf("%s", msg);
printf("You said: %s\n", msg);
if (strlen(msg)<10)
free(msg);
return EXIT_SUCCESS;
}
答案 0 :(得分:3)
使用fgets
代替,scanf
不是缓冲区安全的。你看到的是Undefined Behavior。
答案 1 :(得分:0)
使用 scanf()时,您可以分配“安全”的大尺寸。在用户输入时,它应该是2行(cca.2x80字符),如果文件更大。
结论: scanf()是一种快速而又脏的东西,不要在严肃的项目中使用它。
答案 2 :(得分:0)
您可以使用scanf()
格式字符串
scanf("%9s", msg);
答案 3 :(得分:0)
我认为malloc()
会分配与字边界对齐的内存块。在32位计算机上,这意味着你要求的任何内容都会向上舍入到最接近的4的倍数。这意味着你可能得到一个至少11个字符的字符串(加上{{ 1}}终结者)没有遇到任何问题。
但是,不要认为这是事实。像其他人一样,如果你想避免问题,你应该始终在格式字符串中指定一个安全的最大长度。
答案 4 :(得分:0)
它没有崩溃,因为c非常宽松,与普遍看法相反。如果缓冲区溢出,程序不需要崩溃甚至抱怨。假设您定义
union{
uint8_t a[3]
uint32_t b
}
然后a [4]是非常好的内存并且没有理由崩溃(但是永远不会这样做)。即使是[5]或[100]也可能完全没问题。 另一方面,我可能会尝试访问[-1],这恰好是操作系统不允许您访问的内存,从而导致段错误。
关于你应该做些什么来解决这个问题:正如其他人指出的那样,scanf与缓冲区一起使用是不安全的。使用他们的建议。