在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?谢谢!
答案 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
。