所以我的理解是,一个C字符串,例如“0123456789”,实际上会占用一个11个字符的数组,10个字符用于正文,一个用于终止空字符串。如果这是真的那么为什么下面的代码不会导致某种错误?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv){
char * my_string = "0123456789";
/* my string should occupy 11 bytes */
int my_len = strlen(my_string);
/* however, strlen should only return 10,
because it does not count the null byte */
char * new_string = malloc(my_len);
/* allocate memory 10 bytes wide */
memcpy(new_string, my_string, my_len);
/* copy the first 10 bytes from my_string to new_string
new_string should NOT be null terminated if my understanding
is correct? */
printf("%s\n", new_string);
/* Since new_stirng is NOT null terminated it seems like this should
cause some sort of memory exception.
WHY DOES THIS NOT CAUSE AN ERROR?
*/
return 0;
}
由于new_string
不是空终止,我希望printf
只能永远读取,直到它到达其他应用程序内存,或者在某处随机放置0x00并且崩溃或打印出奇怪的东西。发生了什么事?
答案 0 :(得分:4)
您已创建undefined behavior。该行为取决于编译器和平台。它可能会崩溃。它可以工作。它可以让你敬酒。它可能会使你的计算机崩溃成一个奇点并吸收太阳系。
在您的情况下,new_string[11]
的内存可能已经是0
,即'\0'
,或者是终止空字符。
答案 1 :(得分:3)
因为它是未定义的行为。未定义的行为并不意味着seg故障,尽管这是一种可能性。
答案 2 :(得分:3)
在你的情况下,你从malloc获得的特定内存块以前从未使用过(由你的程序),并且在分配时它可能被操作系统零初始化。因此,第11个字节可能为零,因此没有错误。在运行时间较长的程序中,malloc可以返回第11个字节不为0的脏内存块,因此您将在printf语句中遇到问题。在实践中,您将打印垃圾(直到遇到第一个空)或者如果在分配区域结束之前没有空,则打印段错误。
(正如其他人所说,这种行为是正式未定义的,我只是在解释你所看到的内容)。
答案 3 :(得分:1)
或在某处随机放置0x00 ...打印一些奇怪的东西。
这是常见的行为。实际发生的事情是未定义的。
答案 4 :(得分:0)
这是未定义的行为。在某些情况下,它可能会导致崩溃,这取决于我想象的内存布局