1

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

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);
4

3 回答 3

2

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

在 Unix 系统上,分配的内存通常来自两个系统调用之一:sbrk()mmap(),因此malloc()实现通常会调用这两个函数之一。该malloc()函数是库函数,而不是系统调用,您会看到(这解释了为什么它在手册的第 3 节中,而sbrk()mmap()在第 2 节中)。

对于小型分配,例如您的示例中的 10 个字节,malloc()通常会将许多分配组合成一个更大的分配,并且某些实现使用sbrk(). 对于大型分配,例如我的示例中的 16 MiB,malloc()只需调用mmap()并完成它。

于 2013-07-06T16:23:56.380 回答
1

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

您可以在代码末尾添加睡眠,然后重新编译并再次运行程序。然后阅读“/proc/Process_ID/maps”,您会看到堆在较低的 4GB 中:

% 猫 /proc/26375/maps

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 [堆]
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 [堆栈]
7fff44500000-7fff44501000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
于 2013-07-07T19:44:05.327 回答
0

如果您的系统有 64 位指针,则两者都返回 64 位地址。碰巧它会malloc返回一个将前 32 位设置为 0 的值。为什么这完全取决于您的实现 - 因为您的问题已被标记linux,您可以查看源代码以找出答案!

于 2013-07-06T16:18:20.030 回答