C / C ++ - 当我为一个int分配空间时,为什么堆如此之大?

时间:2014-05-29 16:10:08

标签: c++ c gdb heap

我目前正在使用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,这只是一个测试)。

2 个答案:

答案 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);