scanf读取比目标var可以容纳的更多的字符

时间:2013-10-30 12:32:50

标签: c

以下代码从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;
 }

5 个答案:

答案 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与缓冲区一起使用是不安全的。使用他们的建议。