1

以下代码最多读取 10 个字符stdin并输出这些字符。
当我输入超过 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;
 }
4

5 回答 5

3

改为使用fgetsscanf不是缓冲安全的。你看到的是Undefined Behavior

于 2013-10-30T12:34:25.820 回答
0

使用scanf()时,您可以分配“安全”的大尺寸。在用户输入时,它应该是 2 行(cca. 2x80 字符),以防文件更大一些。

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

于 2013-10-30T12:38:40.247 回答
0

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

scanf("%9s", msg);
于 2013-10-30T12:39:36.057 回答
0

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

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

于 2013-10-30T12:46:00.523 回答
0

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

union{
 uint8_t a[3]
 uint32_t b
}

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

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

于 2013-10-30T12:57:27.050 回答