有人可以向我解释这个奇特的输出:
#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位机器填充问题的原因吗?
答案 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
的实施情况,您的系统可能正在使用p
和q
之间的内存来存储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个字节。