【发布时间】:2020-05-05 13:26:43
【问题描述】:
我怀疑数组的长度是如何分配的
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "s";
long unsigned a = strlen(str);
scanf("%s", str);
printf("%s\n%lu\n", str, a);
return 0;
}
在上面的程序中,我将字符串"s" 分配给char 数组。
我认为str[] 的长度是1。所以我们不能存储超过数组的长度。但它的行为不同。如果我使用scanf 读取一个字符串,它将存储在str[] 中,没有任何错误。数组str 的长度是多少?
示例 I/O:
Hello
Hello 1
【问题讨论】:
-
这是未定义的行为,可能会导致难以追踪的错误,所以不要越界。
-
今天可能没有错误,但明天会有。如果你打破了速度限制,你不一定会造成事故。只有当你撞到东西时。在这里,你的越界字符串没有命中任何东西。
-
如果您有未定义的行为,则崩溃是第二好的情况行为。最好的情况是编译器错误/警告,但在许多情况下,C 编译器不会为此类事情提供任何诊断。如果您在缓冲区末尾之外写入可能会发生更糟糕的事情:任意代码执行,即代码中存在严重的安全漏洞,数据完整性受损,数据机密性......
-
关于:
scanf("%s", str);1) 始终检查返回值(不是参数值)以确保操作成功。注意:scanf()系列函数返回成功的input format conversion说明符(或 EOF)的数量 在当前场景中,任何返回值不是 1 都表示发生了错误。 2) (注意缓冲区str[]的长度为 2)当使用说明符时:%s和/或%[...]总是包含一个比输入缓冲区长度小 1 的 MAX CHARACTERS 修饰符,因为这些说明符总是附加一个 NUL 字节。 (续) -
(cont) 这也避免了缓冲区溢出的任何可能性以及由此产生的未定义行为