我目前正在使用gdb来查看低级代码的效果.现在我正在做以下事情:
int* pointer = (int*)calloc(1, sizeof(int));
Run Code Online (Sandbox Code Playgroud)
然而,当我info proc mappings在gdb中检查内存时,我看到以下内容之后,我认为是.text部分(因为Objfile显示了我正在调试的二进制文件的名称):
...
Start Addr End Addr Size Offset Objfile
0x602000 0x623000 0x21000 0x0 [heap]
Run Code Online (Sandbox Code Playgroud)
当我所做的只是为一个int分配空间时,堆是怎么回事?
最奇怪的是,即使我正在做calloc(1000, sizeof(int))堆的大小仍然是相同的.
PS:我在x86_64机器上运行Ubuntu 14.04.我正在使用g ++编译源代码(是的,我知道我不应该在C++中使用calloc,这只是一个测试).
Ser*_*kov 10
当我所做的只是为一个int分配空间时,堆是怎么回事?
我在Linux上做了一个简单的测试.当一个人calloc在某个时刻调用glibc调用sbrk()来从OS获取内存时:
(gdb) bt
#0 0x0000003a1d8e0a0a in brk () from /lib64/libc.so.6
#1 0x0000003a1d8e0ad7 in sbrk () from /lib64/libc.so.6
#2 0x0000003a1d87da49 in __default_morecore () from /lib64/libc.so.6
#3 0x0000003a1d87a0aa in _int_malloc () from /lib64/libc.so.6
#4 0x0000003a1d87a991 in malloc () from /lib64/libc.so.6
#5 0x0000003a1d87a89a in calloc () from /lib64/libc.so.6
#6 0x000000000040053a in main () at main.c:6
Run Code Online (Sandbox Code Playgroud)
但是glibc不要求操作系统获得你要求的4个字节.glibc计算自己的大小.这是在glibc中完成的:
/* Request enough space for nb + pad + overhead */
size = nb + mp_.top_pad + MINSIZE;
Run Code Online (Sandbox Code Playgroud)
mp_.top_pad默认为128*1024字节,因此当您要求4个字节时,系统分配0x21000字节是主要原因.
您可以通过调用来调整mp_.top_pad mallopt.这是来自mallopt的doc:
M_TOP_PAD
This parameter defines the amount of padding to employ when
calling sbrk(2) to modify the program break. (The measurement
unit for this parameter is bytes.) This parameter has an
effect in the following circumstances:
* When the program break is increased, then M_TOP_PAD bytes
are added to the sbrk(2) request.
In either case, the amount of padding is always rounded to a
system page boundary.
Run Code Online (Sandbox Code Playgroud)
所以我改变了你的程序并添加了mallopt:
#include <stdlib.h>
#include <malloc.h>
int main()
{
mallopt(M_TOP_PAD, 1);
int* pointer = (int*)calloc(1, sizeof(int));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我设置了1个字节的填充,根据doc,它必须是be always rounded to a system page boundary.
所以这就是gdb告诉我的程序:
Start Addr End Addr Size Offset objfile
0x601000 0x602000 0x1000 0x0 [heap]
Run Code Online (Sandbox Code Playgroud)
所以现在堆是4096字节.正是我的页面大小:
(gdb) !getconf PAGE_SIZE
4096
Run Code Online (Sandbox Code Playgroud)
有用的链接: