cmemory-managementheap-memorysegmentdata-segment

Why global variables are stored in heap?


Why in the following example the global variables are stored in the heap segment, instead of the data/bss segment?

From the following output of the maps pseudo-file, the data/bss segment is the 3rd line. This is because it is read/write, and anonymous. The following 2 entries are the heap (as the label indicates).

This is the output of the /proc//maps:

00400000-00405000 r-xp 00000000 08:02 17962770                       myexec
00604000-00605000 r--p 00004000 08:02 17962770                       myexec
00605000-00606000 rw-p 00005000 08:02 17962770                       myexec
00606000-00607000 rw-p 00000000 00:00 0                              [heap]
00607000-00642000 rw-p 00000000 00:00 0                              [heap]
7ffff7a15000-7ffff7bd0000 r-xp 00000000 08:02 22282470               ..libc2.19.so
7ffff7bd0000-7ffff7dcf000 ---p 001bb000 08:02 22282470               ..libc-.19.so
7ffff7dcf000-7ffff7dd3000 r--p 001ba000 08:02 22282470               ..libc-.19.so
7ffff7dd3000-7ffff7dd5000 rw-p 001be000 08:02 22282470               ..libc-.19.so
7ffff7dd5000-7ffff7dda000 rw-p 00000000 00:00 0 
7ffff7dda000-7ffff7dfd000 r-xp 00000000 08:02 22282466               ..ld-2.19.so
7ffff7fec000-7ffff7fef000 rw-p 00000000 00:00 0 
7ffff7ff6000-7ffff7ff7000 rw-p 00000000 00:00 0 
7ffff7ff7000-7ffff7ffa000 rw-p 00000000 00:00 0 
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0                       [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00022000 08:02 22282466                ..ld-2.19.so
7ffff7ffd000-7ffff7ffe000 rw-p 00023000 08:02 22282466                ..ld-2.19.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                       [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0               [vsyscall]

However, when I print the location of 2 global variables, I get the following addresses that belong to the heap vm area:

glb1:6061b0 glb2:6061c0

I print the locations using:

printf("glb1:%lx glb2:%lx\n", (uint64_t) &glb1, (uint64_t) &glb2);

Solution

  • The BSS/DATA is the segment with all the globally defined variables, initialized to a specific value or to zero by default. This segment is part of the executable image.

    The heap "segment" is just the amount of additional storage that will be allocated at program load. It is not contained in the image. This amount follows at the end of the BSS/DATA segment.

    Hence the BSS/DATA and heap segment have the same base address. Think of the heap segment as virtual/as a virtual extentsion of the bss/data segment of the image.

    Lastly, note that often the stack "segment" is added again to this amount and, whereas the heap grows up, the stack grows down. (This may be compiler dependent.)