2013-07-06 38 views
1

为什么mmap()返回64位地址,而malloc()返回32位地址?mmap()vs malloc()返回地址

char *a = (char *)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 
printf("%p\n", a); // example: 0x7fbfbb065000 

char *b = (char *)malloc(10); // example: 0x23bf010 
printf("%p\n", b); 
+2

你并不需要把返回C程序中'malloc'(或'mmap')的值。 –

+1

这完全依赖于实现并且没有趣味。 – 2013-07-06 16:18:04

+0

尝试获得并再次检查 –

回答

1

内核将内存堆放置在较低的4GB内,这就是为什么malloc(3)返回一个64位地址并清除所有高32位的结果。

您可以在代码末尾添加休眠,并重新编译&再次运行该程序。然后阅读 “的/ proc/PROCESS_ID /地图”,你会看到堆在较低4GB:

%执行cat/proc/26375 /图

 
00400000-00401000 r-xp 00000000 ca:01 46177        /root/c/a.out 
00600000-00601000 r--p 00000000 ca:01 46177        /root/c/a.out 
00601000-00602000 rw-p 00001000 ca:01 46177        /root/c/a.out 
01e03000-01e24000 rw-p 00000000 00:00 0         [heap] 
7f654038c000-7f6540541000 r-xp 00000000 ca:01 395503      /lib/x86_64-linux-gnu/libc-2.15.so 
7f6540541000-7f6540740000 ---p 001b5000 ca:01 395503      /lib/x86_64-linux-gnu/libc-2.15.so 
7f6540740000-7f6540744000 r--p 001b4000 ca:01 395503      /lib/x86_64-linux-gnu/libc-2.15.so 
7f6540744000-7f6540746000 rw-p 001b8000 ca:01 395503      /lib/x86_64-linux-gnu/libc-2.15.so 
7f6540746000-7f654074b000 rw-p 00000000 00:00 0 
7f654074b000-7f654076d000 r-xp 00000000 ca:01 395517      /lib/x86_64-linux-gnu/ld-2.15.so 
7f6540960000-7f6540963000 rw-p 00000000 00:00 0 
7f654096a000-7f654096d000 rw-p 00000000 00:00 0 
7f654096d000-7f654096e000 r--p 00022000 ca:01 395517      /lib/x86_64-linux-gnu/ld-2.15.so 
7f654096e000-7f6540970000 rw-p 00023000 ca:01 395517      /lib/x86_64-linux-gnu/ld-2.15.so 
7fff4445e000-7fff4447f000 rw-p 00000000 00:00 0       [stack] 
7fff44500000-7fff44501000 r-xp 00000000 00:00 0       [vdso] 
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 
0

如果您的系统有64位指针,则返回一个64位地址。它只是发生,malloc是让你回到前32位设置为0.为什么这是完全依赖于你的实现 - 因为你的问题被标记为linux,你可以去找出来的源头找出!

2

这实际上只是您的malloc()mmap()实现的实现细节。尝试将分配大小更改为16 MiB,您可能会看到与mmap()malloc()非常相似的结果。

在Unix系统中,分配的内存通常来自于两个系统的一个电话:sbrk()mmap(),所以malloc()实施通常会调用这两个功能之一。函数malloc()是一个库函数,不是系统调用,您可以看到(这解释了为什么在手册的第3部分中,而sbrk()mmap()在第2节中)。

对于小分配(例如在您的示例中为10个字节),malloc()通常会将许多分配归入一个较大的分配,并且某些实现使用sbrk()。对于大型分配,例如我的示例中的16 MiB,malloc()将只需拨打mmap()并完成它。