我目前正在使用gdb来查看低级代码的效果。现在我正在做以下事情:
int* pointer = (int*)calloc(1, sizeof(int));
然而当我在gdb中使用info proc mappings
检查内存时,我看到以下内容之后,我认为是.text部分(因为Objfile显示了我调试的二进制文件的名称):
...
Start Addr End Addr Size Offset Objfile
0x602000 0x623000 0x21000 0x0 [heap]
当我所做的只是为一个int分配空间时,堆如何变大呢?
最奇怪的是,即使我在做calloc(1000, sizeof(int))
时,堆的大小仍保持不变。
PS:我在x86_64机器上运行Ubuntu 14.04。我使用g ++编译源代码(是的,我知道我不应该在C ++中使用calloc,这只是一个测试)。
答案 0 :(得分:9)
当我所做的只是为一个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
但是glibc
并没有要求操作系统获得您提出的4个字节。 glibc
计算自己的大小。这是在glibc中完成的:
/* Request enough space for nb + pad + overhead */
size = nb + mp_.top_pad + MINSIZE;
mp_.top_pad默认为128 * 1024字节,因此当您要求4个字节时,系统分配0x21000字节是主要原因。
您可以通过调用mallopt
来调整mp_.top_pad。这是来自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.
所以我改变了你的程序并添加了mallopt:
#include <stdlib.h>
#include <malloc.h>
int main()
{
mallopt(M_TOP_PAD, 1);
int* pointer = (int*)calloc(1, sizeof(int));
return 0;
}
我设置了1个字节的填充,根据doc,它必须是be always rounded to a system page boundary
。
所以这就是gdb告诉我的程序:
Start Addr End Addr Size Offset objfile
0x601000 0x602000 0x1000 0x0 [heap]
所以现在堆是4096字节。正是我的页面大小:
(gdb) !getconf PAGE_SIZE
4096
有用的链接:
答案 1 :(得分:-4)
既然你已经提到过,C / C ++,最好使用以下结构:
int* pointer = new int(1);