这是我的程序:
#include <stdio.h>
#include <stdlib.h>
main(){
char *p1, *p2, *p3, *p4;
p1 = (char*)malloc(10);
p2 = (char*)malloc(10);
p3 = (char*)malloc(16);
p4 = (char*)malloc(32);
printf("p1 points at: %dn", p1);
printf("p2 points at: %dn", p2);
printf("p3 points at: %dn", p3);
printf("p4 points at: %dnn", p4);
system("PAUSE");
}
这在我的PC上产生以下输出:
P1点:6492080
p2点:6492104
p3点:6492128
P4点:6492152
因此,无论分配多少个字节,Malloc分配的每个内存空间都会进一步启动24个字节。这是为什么?我感谢您的帮助!
malloc
的确切行为由您的特定植入术(Compiler/libc/os)确定。通过打印地址,您的程序从事不确定的行为。
如果您通过告诉我们您使用的是什么编译器,使用什么OS,什么架构以及您使用的LIBC版本来缩小问题的范围,那么我们也许可以给出更具体的答案该实现以及为什么数字为24。
我的猜测是在您的实现中,每个malloc
ED内存区域都需要从8个倍数的地址开始,而且还有8个字节的开销。
编辑:如果您再次调用malloc
以在P4之后创建P5,则该模式绝对无法继续,因此您对" Malloc分配的每个内存空间的说明"进一步启动24个字节,无论多少个字节分配。"是错误的。
不能保证int
和某些void*
或char*
指针具有相同的尺寸(在我的Debian/Linux/AMD64系统上,int
-S是32位,但指针为64位))。您可能需要包括<stdint.h>
并使用intptr_t
。
malloc
的实施有时可能会在分配的区域之前保留几个字节,以进行管家目的。 malloc
shoud始终返回足够的对齐指针(对齐约束是编译器,运行时和处理器特定的)。绝对不能保证malloc
会返回越来越多的及时结果(尤其是在实际程序中,在这种情况下,malloc
的数百万个呼叫与free
的数百万个呼叫混合在一起;您甚至在如此长的运行过程中可能会有一些内存片段)。
我很确定,如果您在p4
之后添加p5 = malloc(10120);
,则不会在p5
和p4
之间看到24字节的距离,因为当它成功的malloc
确保其结果不是任何先前结果的别名时,因此,p5
至少应具有p4
的32个字节(包含32个字节块)。
几乎总是,标准C库在某些较低级别的原始词上方实现malloc
,通常某些SYSCALL以获取连续的虚拟内存页面。在Linux上,这些SYSCALL通常是MMAP(2)(也许使用sbrk(2)
),并且由于Linux系统大多是免费的软件,因此您实际上可以研究并改善malloc
的实现,例如。MUSL LIBC实施Malloc(更常见的GNU LIBC malloc
实施也许更复杂)。因此,您可以通过切换到Linux来了解更多。
malloc
的实现在理论上可能总是失败。实际上,malloc
可能会成功,但您应该始终测试失败情况。
当然,大多数实现都关心free
并重新使用最近的free
-D存储区(如果可能的话,没有任何SYSCALLS)在其malloc
实现中。如何组织堆能够使malloc
和free
有效地有效(如果您希望它非常好,可能仍然是研究主题)。
您可能想阅读Malloc上的Wikipedia页面。
malloc
应为size
大小的对象分配空间。例如,没有什么可以阻止您的实现来添加用于对齐用途的填充字节。另一个示例:某些内存管理实现在分配空间之前保持块的大小。
如果您需要更多详细信息,则应精确实现。