只是好奇,为什么这不会导致seg错误?

时间:2012-06-01 20:43:51

标签: c char segmentation-fault

所以我的理解是,一个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并且崩溃或打印出奇怪的东西。发生了什么事?

5 个答案:

答案 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)

这是未定义的行为。在某些情况下,它可能会导致崩溃,这取决于我想象的内存布局