简体   繁体   English

只是出于好奇,为什么这不会造成段错误?

[英]Just curiosity, why does this not cause a seg fault?

So it is my understanding that a C string of, for instance "0123456789", would actually occupy an array of 11 chars, 10 chars for the body and one for the terminating null. 因此,据我了解,一个C字符串(例如“ 0123456789”)实际上将占用11个字符的数组,主体为10个字符,而终止为null的一个字符。 If that is true then why does the code below NOT cause some sort of error? 如果是这样,那么为什么下面的代码不会引起某种错误?

#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;
}

Since new_string is not null terminated I would expect printf to just read forever until it reaches some other applications memory, or a randomly placed 0x00 somewhere and either crash or print something strange. 由于new_string不是以null结尾的,所以我希望printf永远读下去,直到到达其他应用程序的内存,或者在某个位置随机放置0x00并崩溃或打印出奇怪的东西。 What's going on? 这是怎么回事?

You have created undefined behavior . 您已经创建了未定义的行为 The behavior is compiler and platform dependent. 该行为取决于编译器和平台。 It could crash. 可能会崩溃。 It could work. 它可以工作。 It could make you toast. 它可能使您敬酒。 It could collapse your computer into a singularity and absorb the solar system. 它可能会使您的计算机崩溃,并吸收太阳系。

In your case, it's likely that the memory at new_string[11] was already 0 , which is '\\0' , or the terminating-null character. 在您的情况下, new_string[11]处的内存可能已经为0 ,即为'\\0'或终止空字符。

Because it's undefined behavior. 因为它是未定义的行为。 Undefined behavior does not mean a seg fault, although that's one possibility. 未定义的行为并不意味着段错误,尽管这是一种可能。

In your case, the particular memory block you got from malloc was never used before (by your program), and it was probably zero-initialized by the OS when it was allocated. 在您的情况下,从malloc获得的特定内存块之前(程序)从未使用过,并且在分配时可能由OS初始化为零。 Therefore, the 11th byte was likely a zero, and so no error. 因此,第11个字节可能为零,因此没有错误。 In a longer-running program, malloc can return a dirty chunk of memory where the 11th byte is not 0, and so you will run into problems at the printf statement. 在运行时间更长的程序中,malloc可以返回第11个字节不为0的脏内存块,因此您将在printf语句中遇到问题。 In practice, you'll either print garbage (until the first null is encountered) or segfault if there is no null before the end of the allocated region. 在实践中,如果分配的区域的末尾没有null,则将打印垃圾(直到遇到第一个null)。

(As others have said, the behavior is formally undefined, I'm just explaining what you saw). (正如其他人所说,行为在形式上是不确定的,我只是在解释您所看到的)。

or a randomly placed 0x00 somewhere ... print something strange. 或在某处随机放置的0x00 ...打印一些奇怪的东西。

This is commonly observed behavior. 这是通常观察到的行为。 What will actually happen is undefined. 实际发生的情况是不确定的。

This is undefined behaviour. 这是未定义的行为。 In some cases it could cause a crash it would depend on the memory layout I would imagine 在某些情况下,它可能导致崩溃,这取决于我想像的内存布局

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM