scanf 读取的字符数超过了目标 var 可以容纳的字符数



以下代码从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: %sn", msg);
     if (strlen(msg)<10)
         free(msg);
     return EXIT_SUCCESS;
 }

请改用fgetsscanf不是缓冲区安全的。你看到的是未定义的行为。

使用 scanf() 时,您可以分配"安全"的大尺寸。在用户输入时,它应该是 2 行(抄送 2x80 个字符),如果文件更大。

结论:scanf() 是一个快速而肮脏的东西,不要在严肃的项目中使用它。

您可以在scanf()格式字符串中指定最大大小

scanf("%9s", msg);

我想malloc()分配与单词边界对齐的内存块。在 32 位机器上,这意味着您要求的任何内容都将四舍五入到最接近的 4 的倍数。这意味着您可能会使用至少 11 个字符的字符串(加上一个''终止符)而不会遇到任何问题。

但永远不要假设是这种情况。就像其他人所说的那样,如果要避免出现问题,则应始终在格式字符串中指定安全的最大长度。

它不会崩溃,因为 c 非常宽松,与流行的看法相反。如果缓冲区溢出,程序不需要崩溃甚至抱怨。假设你定义

union{
 uint8_t a[3]
 uint32_t b
}

那么 a[4] 是完全好的内存,没有理由崩溃(但永远不要这样做)。即使是 a[5] 或 a[100] 也可能完全没问题。另一方面,我可能会尝试访问 a[-1],它恰好是操作系统不允许您访问的内存,从而导致段错误。

至于你应该怎么做来解决这个问题:正如其他人指出的那样,scanf 与缓冲区一起使用是不安全的。在他们的建议上使用。

最新更新