puts() 如何在没有 \0 终止符的情况下找到数组的末尾?

How can puts() find the end of an array without a \0 terminator?

在此代码中:

int length = atoi(argv[1]);
char *tab = malloc(length * sizeof(char));
memset(tab, '-', length);
puts(tab);

无论我向 argv[1] 传递什么值,输出都是正确的。例如,对于 argv[1] = "5",我得到 -----(五个连字符)。

我想知道当我没有在 char 数组的末尾放置 '\0' 时,puts() 如何找到输入字符串的末尾。

@aschepler 说的。我猜某些东西——无论是操作系统还是你的 C 运行时或启动代码——在你 malloc 之前将内存清零。结果,由于您没有覆盖已经存在的 [=11=] 字节,因此您的字符串以 null 结尾。不要以为这将永远有效!

编辑 不同的编译器、操作系统和库以不同方式初始化内存。 This question and its answers, and likewise this one, give some examples of initialization patterns and other patterns written to memory to assist debugging. Turns out at least one compiler (IBM XLC) lets you choose the value for uninitialized automatics.

正如上面@cxw 所述,您很幸运(或者您的系统只是将您的内存归零为 malloc),您的字符串在其内容后包含一个 [=10=]

我还想补充一点,您不应该依赖这些方法,因为它会使您的程序不稳定并容易崩溃。在这种情况下,您最终会遇到无效读取错误,但如果您的 malloc 更大,您将读取未初始化的内存。

您可能需要使用 Valgrind 等工具来发现内存问题。 始终记住,在发布程序之前应修复任何内存错误,因为崩溃很可能取决于程序执行的平台,而且还因为此类错误可能被恶意使用。

尝试 0、1、1000、1000000、1000000000、1000000000000、-1 等值。

一个人从商店偷了一些东西却没有被抓到,这样偷东西就可以了吗?尝试偷走整个商店,看看是否 "works"。

puts() 需要一个 字符串 ,这意味着 空字符 肯定会结束它 - 否则它不是 字符串。如果代码违反规则,puts() 没有义务以某种方式行事。这是未定义的行为 (UB)。


顺便说一句,代码还应该在 memset(tab, '-', length);

中使用它之前检查是否 tab != NULL