结构的内存分配

时间:2010-10-07 17:53:21

标签: c

有人可以向我解释这个奇特的输出:

#include <stdio.h>

typedef struct node
{
  int i;
  struct node *next;
}node;

main()
{
    node *p,*q;
    printf(" %u ",sizeof(node));              // 16
    p = (node *)malloc(sizeof ( node ) ) ;     
    printf(" %p ",p);                    // 0x1cea010
    q = (node *)malloc(sizeof ( node ) ) ; 
    printf("\n %p ",q);                    // 0x1cea030
}

我有一个64位处理器。当大小显示为16个字节时,为什么要为节点分配32个字节? 我检查了一台32位机器。地址有8个字节的间隔。没有填充和东西。那么4字节的差异仅仅是64位机器填充问题的原因吗?

6 个答案:

答案 0 :(得分:7)

两个malloc调用不一定会返回连续的内存区域。进行此测试的更好方法是:

main()
{
    node *p;
    printf(" %u ",sizeof(node));
    p = (node*)malloc(2 * sizeof (node));     
    printf(" %p \n %p ", &p[0], &p[1]);
    free(p);
}

通过分配数组,您可以确保它们在内存中背靠背。

根据您malloc的实施情况,您的系统可能正在使用pq之间的内存来存储realloc,{{{}使用的簿记信息1}}和朋友们。

答案 1 :(得分:2)

地址malloc()返回由操作系统的内存规划算法决定。您无法保证彼此跟随的两个malloc调用将使内存段相互跟随。这就是说,你的代码不会为p分配32个字节,它会分配16个。超过16个字节的任何写入/读取都有未定义的行为并且可能导致程序崩溃。这同样适用于q

答案 2 :(得分:1)

分配内存时,分配器还需要包含有关刚刚分配的块的一些信息。这可能是额外的16个字节来自的地方。此外,分配器可能会强制执行最小块大小以帮助防止碎片。还有一些对齐问题需要考虑。

答案 3 :(得分:0)

node *p,q;

与:

相同
node *p;
node q;

所以

q =(node *)malloc(sizeof(node));

是错误,因为您正在为结构指定指针值。

您也没有包含或者,因此您的编译器不知道malloc的签名是什么,这可能就是为什么您没有收到错误或警告消息提醒您错误的分配。< / p>

如果您询问两个malloc ed内存区域之间的空间,malloc不必(通常不会)连续分配内存区域。它通常会分配一个最小的块(较小的数量向上舍入),并且在malloc返回的指针之前可能还有一些簿记数据。

答案 4 :(得分:0)

为什么总结malloc为一个节点分配了32个字节?它们不一定是连续的。顺便说一下,malloc的实现可能需要一些额外的空间来存储簿记信息。

答案 5 :(得分:0)

malloc()不保证连续调用中的连续内存块。它甚至可能不会返回同一页面的两个部分。

通常一个坏主意来假设动态请求并由malloc()返回的内存。如果要采取任何措施,最好认为您已经获得您要求的确切字节数,并且它们位于内存中的某个隔离位置

也就是说,malloc()比人们想象的要聪明得多。如果您分配了相同大小的更多结构,或者决定重新分配相同的结构,它可能会跳过这16个字节。