C/C++ - Why is the heap so big when I'm allocating space for a single int?

c, c++, gdb, heap-memory

Solution

How come the heap is that big when all I did was allocating space for a single int?

I did a simple test on Linux. When one calls `calloc` glibc calls at some point sbrk() to get memory from 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

But `glibc` does not ask OS to get exactly 4 bytes that you have asked. `glibc` calculates its own size. This is how it is done in glibc:

  /* Request enough space for nb + pad + overhead */
  size = nb + mp_.top_pad + MINSIZE;

mp_.top_pad is by default 128*1024 bytes so it is the main reason why when you ask for 4 bytes the system allocates 0x21000 bytes.

You can adjust mp_.top_pad with call to `mallopt`. This is from mallopt's 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.

So I changed you progam and added mallopt:

#include <stdlib.h>
#include <malloc.h>
int main()
{
  mallopt(M_TOP_PAD, 1);
  int* pointer = (int*)calloc(1, sizeof(int));
  return 0;
}

I set 1 byte padding and according to doc it must be `be always rounded to a system page boundary`.

So this is what gdb tells me for my program:

      Start Addr           End Addr       Size     Offset objfile
        0x601000           0x602000     0x1000        0x0 [heap]

So now the heap is 4096 bytes. Exactly the size of my page:

(gdb) !getconf PAGE_SIZE
4096

Useful links:

- http://man7.org/linux/man-pages/man3/mallopt.3.html

Problem

I'm currently using gdb to see the effects of low level code. Right now I'm doing the following: ``` int* pointer = (int*)calloc(1, sizeof(int)); ``` yet when I examine the memory using `info proc mappings` in gdb, I see the following after what I presume is the .text section (since Objfile shows the name of the binary I'm debugging): ``` ... Start Addr End Addr Size Offset Objfile 0x602000 0x623000 0x21000 0x0 [heap] ``` How come the heap is that big when all I did was allocating space for a single int? The weirdest thing is, even when I'm doing `calloc(1000, sizeof(int))` the size of the heap remains the same. PS: I'm running Ubuntu 14.04 on an x86_64 machine. I'm compiling the source using g++ (yes, I know I shouldn't use calloc in C++, this is just a test).

Original source

Related problems