如果我连续两次malloc(1),为什么这些值相差32?

时间:2014-04-06 20:40:25

标签: c memory malloc

在C中,如果我运行malloc(1)两次然后打印输出到uintptr_t的两个值,则值相差32。例如,

void * last = malloc(1);
void * next = malloc(1);
printf("orig %lu\n", ((uintptr_t)last));
printf("next %lu\n", ((uintptr_t)next));

打印出来

orig 30572560
next 30572592
根据{{​​3}},

malloc(size_t size)分配大小字节。当I malloc一个字节,然后是另一个字节时,我希望该值增加8。为什么它们相差32?谢谢!

5 个答案:

答案 0 :(得分:5)

这实际上是不同编译器/标准libriaries之间不同的实现细节。通常,无法保证随后的malloc调用将返回相邻的内存区域。另请注意,每个内存区域都与其他元数据相关联,包括但不限于区域大小(否则,在运行free时无法知道要释放多少内存)。此元数据通常放在已分配的区域内,使其大于请求的大小。还有一些其他因素会影响实际分配的内存量 - 内存对齐和malloc实现使用的“漏洞”查找算法等。

答案 1 :(得分:1)

Malloc可能无法保证连续的内存地址。这取决于编译器。另请注意,内存访问是在特定边界处最佳完成的,例如四个字节(或其他体系结构上的八个字节),因此如果malloc确实提供了连续的内存地址,则可以插入填充以避免逐字节寻址。

同样使用%p打印指针,而不是整数。

答案 2 :(得分:1)

因为内存分配器在指定的bounderies上工作。在你的情况下 - 它的32个字节(不是位,字节)。

有一种名为pointer tagging的好方法可以滥用它来节省空间。请参阅此博客文章以了解如何(基本上 - 它们在指针的低位保存状态,并且在读取指针的内容之前,它们将“零”LSB)。

http://jkt.flaska.net/blog/Tagged_pointers__and_saving_memory_in_Trojita.html

答案 3 :(得分:1)

malloc()保证返回指向块的指针,该块至少您请求的大小,并使用正确的对齐方式存储您请求的任何大小的对象或NULL
malloc()如何得到并包裹这些块是完全在这些边界内定义的实现,你不应该以任何方式依赖它。
因为malloc()必须为free()存储一些簿记数据,并且必须保证更大请求的对齐,所以在此实例中的实现以某种方式为您提供了32个字节的块。

除此之外:不允许将指针减去不同的内存块。 此外,您的程序通过尝试打印uintptr_t来激发未定义的行为:正确的格式说明符为PRIdPTR

琐事:让free()无所作为是一个有效的选择,这意味着可以省略簿记数据。

答案 4 :(得分:0)

只有在一次调用Malloc中分配一些块时,

malloc才能确保数据存储在连续内存中(可能会执行一些填充/对齐)。像

这样的东西
char *p = malloc(sizeof(char)*2);

此处p[0]&的地址p[1]将是连续的 但是对于:

char *p1 = malloc(sizeof(char));
char *p2 = malloc(sizeof(char));  

无法保证,它可能/可能找不到连续的内存来分配p1& p2