为什么有那么多结构?

时间:2015-03-08 19:18:33

标签: c malloc

我是初学者,我不明白为什么这段代码不会崩溃。当我使用malloc(1)分配飞机时,怎么会有这么多飞机[i]?

int main()
{

    typedef struct Flight2{
        int altitude;
        int longitude;
        int latitude;

    }Flight;

    Flight *planes;
    planes = (Flight*)malloc(1);
    if (planes == NULL) {
     printf("Error in allocating the data array.\n");

    }
    printf("%d.\n",sizeof(Flight));
    planes[0].altitude = 1000;
    planes[100].altitude = 1200;
    printf("0: %d\n",planes[0].altitude);
    free((void*)planes);
    printf("100: %d",planes[100].altitude);
    return 0;
}

1 个答案:

答案 0 :(得分:3)

首先,您在访问planes数组的第一个位置处有未定义的行为。从那时起,任何事情都可能发生。但是,这里解释了在您的情况下实际上发生了什么。我在这里说的话永远不应该被依赖,但是理解幕后发生的事情是有益的。

您的结构大小为12个字节(至少在我的系统上)。因此,100 Flight个对象需要1200字节的内存。这很重要,因为系统根据内存页面管理进程的内存,而内存页面在X86硬件上有4096字节。那么,会发生什么:

  1. 您从malloc()请求一个字节。

  2. malloc()实现没有内存,但是,它要求系统内核提供内存。

  3. 系统内核至少将整个页面交给malloc()实现。

  4. malloc()实现将一些私有数据写入内存页面,以便能够以很多小块将其返回给您。

  5. malloc()实现返回该页面内的指针。这很可能指向比存储自己的私有数据更高的地址。但这取决于malloc()实施。

  6. 您可以从此指针的偏移0到3和1188-1191写入内存。

    这不会失败,因为它仍在内存页面中,因此硬件和系统内核认为此访问是可以的。 (仅)malloc()的定义与您正在做的事情相冲突。

  7. 由于您没有破坏malloc()实施的任何重要私人数据,free()调用并没有意识到可疑的事情正在发生,并且您的程序正常终止。

  8. 请注意,程序的明显成功行为取决于其中只有一个分配的事实。如果您在第一个之后插入第二个malloc()来电,则可能会因为可能覆盖您malloc()专用的数据而导致崩溃实现。这可能会导致free()使用错误消息中止您的程序,导致其他malloc()调用的错误行为,以任何方式崩溃您的程序或执行任何其他操作。如果在第一个调用之前插入第二个malloc()调用,则可能导致分配发生在内存页面的末尾,可能会给您一个段错误。但是一旦你进入未定义行为的土地,没有什么是肯定的。

    顺便说一下:如果您使用valgrind运行程序,它会告诉您出错的确切位置以及方式。这是一个非常好的工具,你应该熟悉它。