1

在此代码:puts()如何找到没有 0终止符的数组的末尾?

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

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

我在想如何puts()可以找到输入字符串的结尾,当我没有在我的char s数组的末尾加上'\ 0'。

+11

有时未定义行为似乎工作使用前检查tab != NULL。只是你的运气不好。 – aschepler

+1

顺便说一句,删除C++标记 - 这不是(有效的)C++代码,它是纯C – UnholySheep

+1

如果你想纠正它,分配一个额外的字节并添加'*(tab + atoi(argv [1])) ='\ 0';' – byxor

回答

5

@aschepler说什么。我猜测—或者操作系统或者你的C运行时或者启动代码—在你malloc之前正在清零内存。因此,由于您没有覆盖已存在的\0字节,因此您的字符串是空终止的。不要以为这会一直工作!

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

+1

只是一个想法,但我想知道如果内存被''1''掉了,而不是被清零,或者就此而言,只是填充了非零乱码)。 – byxor

+1

@byxor [瞧](http://stackoverflow.com/a/127404/2877364):) – cxw

+1

@myschu如果这个答案,或其他,解决了你的问题到你的满意,请你打对答案旁边的复选标记接受它?这将有助于这个问题的未来读者知道什么对你有用,并将清除没有接受答案的列表中的问题。你和你接受答案的人也将获得声望点:)。 – cxw

0

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

我也想补充一点,你应该不要依赖这样的方法,因为它会让你的程序不稳定并容易崩溃。在这种情况下,你最终会得到一个无效的读取错误,但是如果你的malloc会变大,你会读取未初始化的内存。

您可能希望使用诸如Valgrind之类的工具来识别内存问题。 请务必记住,在发布程序之前应修复任何内存错误,因为崩溃很可能取决于程序在其上执行的平台,还因为可能会恶意使用此类错误。

1

尝试像0,1,1000,1000000,1000000000,1000000000000,-1这样的值。

一个从商店偷了几件东西,并没有被抓到,这是否偷窃行吗?尝试窃取整个商店,看看它是否“有效”。

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


BTW,代码也应在memset(tab, '-', length);

相关问题