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

时间:2017-05-06 12:57:31

标签: c arrays string memory-management dynamic-memory-allocation

在此代码中:

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

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

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

3 个答案:

答案 0 :(得分:5)

@aschepler说的是什么。我猜测某事 - 无论是操作系统还是C运行时或启动代码 - 都在malloc之前将内存归零。因此,由于您没有覆盖已存在的\0字节,因此您的字符串将以空值终止。不要以为这将永远有效!

编辑不同的编译器,操作系统和库以不同方式初始化内存。 This question及其答案,同样this one,给出了一些初始化模式和写入内存的其他模式的示例,以帮助调试。结果至少有一个编译器(IBM XLC)lets you choose the value for uninitialized automatics.

答案 1 :(得分:1)

尝试使用0,1,1000,1000000,1000000000,1000000000000,-1等值。

一个人从商店偷了几件东西而且没有被抓住,这会让你偷东西吗?尝试窃取整个商店,看看它是否“有效”。

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

顺便说一句,在tab != NULL

中使用代码之前,代码还应检查memset(tab, '-', length);是否正确

答案 2 :(得分:0)

如上面的@cxw所述,你很幸运(或者你的系统只是将你的内存归零于malloc),你的字符串在其内容之后保持\0

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

您可能希望使用Valgrind等工具来发现内存问题。 请记住,在发布程序之前应该修复任何内存错误,因为崩溃很可能取决于程序执行的平台,但也可能因为恶意使用这些错误。