使用malloc分配大内存区域后,我试图检查 / proc / [pid] / maps 文件中的堆区域范围。下面是我写的代码。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
void *p = malloc(1024LL * 1024LL * 1024LL * 4);
if (p == NULL)
{
printf("alloc fail\n");
}
//else
//{
//printf("memory allocated at %p\n", p);
//}
while (1) sleep(1);
free(p);
return 0;
}
当我检查 / proc / [pid] / maps 文件时,没有显示堆区域的映射。
00400000-00401000 r-xp 00000000 08:01 20185722 /home/soumen/a.out
00600000-00601000 r--p 00000000 08:01 20185722 /home/soumen/a.out
00601000-00602000 rw-p 00001000 08:01 20185722 /home/soumen/a.out
7f19f98df000-7f1af98e0000 rw-p 00000000 00:00 0
7f1af98e0000-7f1af9a9f000 r-xp 00000000 08:01 23462292 /lib/x86_64-linux-gnu/libc-2.23.so
7f1af9a9f000-7f1af9c9f000 ---p 001bf000 08:01 23462292 /lib/x86_64-linux-gnu/libc-2.23.so
7f1af9c9f000-7f1af9ca3000 r--p 001bf000 08:01 23462292 /lib/x86_64-linux-gnu/libc-2.23.so
7f1af9ca3000-7f1af9ca5000 rw-p 001c3000 08:01 23462292 /lib/x86_64-linux-gnu/libc-2.23.so
7f1af9ca5000-7f1af9ca9000 rw-p 00000000 00:00 0
7f1af9ca9000-7f1af9ccf000 r-xp 00000000 08:01 23462295 /lib/x86_64-linux-gnu/ld-2.23.so
7f1af9ea4000-7f1af9ea7000 rw-p 00000000 00:00 0
7f1af9ecc000-7f1af9ece000 rw-p 00000000 00:00 0
7f1af9ece000-7f1af9ecf000 r--p 00025000 08:01 23462295 /lib/x86_64-linux-gnu/ld-2.23.so
7f1af9ecf000-7f1af9ed0000 rw-p 00026000 08:01 23462295 /lib/x86_64-linux-gnu/ld-2.23.so
7f1af9ed0000-7f1af9ed1000 rw-p 00000000 00:00 0
7ffe71fe1000-7ffe72002000 rw-p 00000000 00:00 0 [stack]
7ffe72094000-7ffe72096000 r--p 00000000 00:00 0 [vvar]
7ffe72096000-7ffe72098000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
现在我取消注释代码中的else部分并再次运行它。这次堆区域出现在 / proc / [pid] / maps 文件中。但它比分配的要小得多。
此外,分配区域的起始地址不在 / proc / [pid] / maps 文件中显示的堆区域限制内。
节目输出:
memory allocated at 0x7fcab87e2010
/ proc / [pid] / maps 文件
的内容00400000-00401000 r-xp 00000000 08:01 20185722 /home/soumen/a.out
00600000-00601000 r--p 00000000 08:01 20185722 /home/soumen/a.out
00601000-00602000 rw-p 00001000 08:01 20185722 /home/soumen/a.out
00bba000-00bdb000 rw-p 00000000 00:00 0 [heap]
7fcab87e2000-7fcbb87e3000 rw-p 00000000 00:00 0
7fcbb87e3000-7fcbb89a2000 r-xp 00000000 08:01 23462292 /lib/x86_64-linux-gnu/libc-2.23.so
7fcbb89a2000-7fcbb8ba2000 ---p 001bf000 08:01 23462292 /lib/x86_64-linux-gnu/libc-2.23.so
7fcbb8ba2000-7fcbb8ba6000 r--p 001bf000 08:01 23462292 /lib/x86_64-linux-gnu/libc-2.23.so
7fcbb8ba6000-7fcbb8ba8000 rw-p 001c3000 08:01 23462292 /lib/x86_64-linux-gnu/libc-2.23.so
7fcbb8ba8000-7fcbb8bac000 rw-p 00000000 00:00 0
7fcbb8bac000-7fcbb8bd2000 r-xp 00000000 08:01 23462295 /lib/x86_64-linux-gnu/ld-2.23.so
7fcbb8da7000-7fcbb8daa000 rw-p 00000000 00:00 0
7fcbb8dcf000-7fcbb8dd1000 rw-p 00000000 00:00 0
7fcbb8dd1000-7fcbb8dd2000 r--p 00025000 08:01 23462295 /lib/x86_64-linux-gnu/ld-2.23.so
7fcbb8dd2000-7fcbb8dd3000 rw-p 00026000 08:01 23462295 /lib/x86_64-linux-gnu/ld-2.23.so
7fcbb8dd3000-7fcbb8dd4000 rw-p 00000000 00:00 0
7fff2df8f000-7fff2dfb0000 rw-p 00000000 00:00 0 [stack]
7fff2dfec000-7fff2dfee000 r--p 00000000 00:00 0 [vvar]
7fff2dfee000-7fff2dff0000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
那么操作系统在这里做了什么? malloc调用是否可以延迟内存分配,直到它被引用?
我正在使用的配置
Linux nightfury 4.4.0-78-generic#99-Ubuntu SMP Thu Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU / Linux
gcc(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609
答案 0 :(得分:3)
C标准没有提及堆的任何内容,因此,malloc()
的实现可以以任何合适的方式自由分配内存。例如,这可以来自不提供内存管理的平台上的数据段中的固定大缓冲区。
对于glibc
,malloc
默认情况下,如果请求的块足够大,则使用mmap
分配内存。传统的堆(通过sbrk
)仅用于较小的分配。