Snakienn
Snakienn

Reputation: 619

Why the stack address is lower than the heap address sometimes?

I always think stack locates at higher address than heap like the picture2. But I found that sometimes the heap address is higher when I test it using cpp(picture1). I know that the virtual memory is used but I also want to know why the virtual address of stack and heap dont follow the picture2? Thank you very much!

enter image description here

enter image description here

Upvotes: 3

Views: 3861

Answers (2)

In practice, the heap data is not necessarily contiguous on recent Linux systems (and probably on most other desktop or server OSes). The virtual address space (VAS) wikipage has also a simplified figure.

On Linux systems, you can experiment with proc(5). Try cat /proc/self/maps which shows on the terminal the virtual address space of the (current) cat process. Try also cat /proc/$$/maps (to get the VAS of your current shell) and (as root) cat /proc/$(pidof Xorg)/maps (to get the VAS of your Xorg server). And try other cat /proc/some-pid/maps for various pids of various processes.

One of the explanation is that sometimes, malloc will call mmap(2) and not only sbrk(2). In particular, malloc of a large memory chunk will use mmap (I think the "threshold" for using mmap could be a malloc of several megabytes). And libraries and application programs can use mmap to access some file.

And mmap is using ASLR so obviously won't give contiguous memory segments. Of course, an application (or the implementation of free) could sometimes use munmap to release memory. And dynamic linking (see ld-linux(8) & dlopen(3) ...) also use mmap and munmap.

So the virtual address space can be (and often is) made of many discontinuous memory segments (sometimes thousands of them).

BTW, multi-threading also wants several memory segments. Generally each thread has its own mmap-ed stack space.

For example, I have some mate-terminal terminal emulator running as process of pid 2594. Its process has 568 memory segments (i.e. lines in /proc/2594/maps). I won't spoil this answer by showing all of them. And the firefox browser process I am typing this answer in has 1229 lines in /proc/1604/maps, here are some of them:

27423e6e0000-27423e720000 r-xp 00000000 00:00 0 
27423e720000-27423e730000 r-xp 00000000 00:00 0 
27423e730000-27423e760000 r-xp 00000000 00:00 0 
27423e760000-27423e780000 r-xp 00000000 00:00 0 
27423e780000-27423e7c0000 r-xp 00000000 00:00 0 
27423e7c0000-27423e7d0000 r-xp 00000000 00:00 0 
27423e7d0000-27423e7e0000 ---p 00000000 00:00 0 
27423e7e0000-27423e7f0000 r-xp 00000000 00:00 0 
7efed334d000-7efed3357000 r--p 00172000 08:01 11275829                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.23
7efed3357000-7efed3359000 rw-p 0017c000 08:01 11275829                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.23
7efed3359000-7efed335c000 rw-p 00000000 00:00 0 
7efed335c000-7efed335f000 r-xp 00000000 08:01 1704007                    /lib/x86_64-linux-gnu/libdl-2.24.so
7efed335f000-7efed355e000 ---p 00003000 08:01 1704007                    /lib/x86_64-linux-gnu/libdl-2.24.so
7efed355e000-7efed355f000 r--p 00002000 08:01 1704007                    /lib/x86_64-linux-gnu/libdl-2.24.so

So your picture is a gross simplification. I'm pretty sure that the fragmentation of the VAS also happens on other operating systems, notably for monster processes like e.g. your web browser.

Upvotes: 1

user3344003
user3344003

Reputation: 21627

Your diagram is just conceptual. It does not reflect the complexities of linking, dynamic loading, relocation, and run time memory allocation.

Upvotes: 1

Related Questions