0

So memory segmentation can be done with or without paging. I always hear people talking about stack and heaps when discussing something memory related in C++. However, what I do not get is that if the program's memory (its virtual address space) is segmented using pages, it won't get divided into stack, heap, etc., right? But rather it is divided into pages without names - in that case (with the assumption that my understanding of segmentation is correct), can you still talk about the stack and heap?

Also, if the virtual address space is divided into pages, where does the stack, heap, data, etc. segments come from?

  • 1
    This isn't really about C++, but about computer architecture. C++ tries to be independent of computer architecture. – hyde Feb 10 '18 at 18:58
2

The stack and heap in C/C++ describe different mechanisms of memory allocation. They can also be called “automatic storage” and “free store”. If you allocate data on the free store/heap, you are responsible for managing the lifetime (calling delete or free()). This is mostly unrelated to memory pages.

Memory pages are a block of virtual addresses. The virtual address space of a process is created by the operating system by mapping pages into the address space.

A process uses different areas of the address space differently. One area will be the stack. Other areas will hold the contents of executable files and libraries. These files may have different segments, e.g. for executable code, for constants, and space for variables.

Here I've pulled the address space mappings of a Perl interpreter using pmap:

0000000000400000   1776K r-x-- perl
00000000007bb000      4K r---- perl
00000000007bc000     12K rw--- perl
00000000007bf000      4K rw---   [ anon ]
0000000001eff000   1192K rw---   [ anon ]
00007f00184b7000   4464K r---- locale-archive
00007f0018913000   1792K r-x-- libc-2.23.so
00007f0018ad3000   2048K ----- libc-2.23.so
00007f0018cd3000     16K r---- libc-2.23.so
00007f0018cd7000      8K rw--- libc-2.23.so
00007f0018cd9000     16K rw---   [ anon ]
00007f0018cdd000     36K r-x-- libcrypt-2.23.so
00007f0018ce6000   2044K ----- libcrypt-2.23.so
00007f0018ee5000      4K r---- libcrypt-2.23.so
00007f0018ee6000      4K rw--- libcrypt-2.23.so
00007f0018ee7000    184K rw---   [ anon ]
00007f0018f15000   1056K r-x-- libm-2.23.so
00007f001901d000   2044K ----- libm-2.23.so
00007f001921c000      4K r---- libm-2.23.so
00007f001921d000      4K rw--- libm-2.23.so
00007f001921e000     12K r-x-- libdl-2.23.so
00007f0019221000   2044K ----- libdl-2.23.so
00007f0019420000      4K r---- libdl-2.23.so
00007f0019421000      4K rw--- libdl-2.23.so
00007f0019422000     96K r-x-- libpthread-2.23.so
00007f001943a000   2044K ----- libpthread-2.23.so
00007f0019639000      4K r---- libpthread-2.23.so
00007f001963a000      4K rw--- libpthread-2.23.so
00007f001963b000     16K rw---   [ anon ]
00007f001963f000    152K r-x-- ld-2.23.so
00007f0019839000     20K rw---   [ anon ]
00007f0019864000      4K r---- ld-2.23.so
00007f0019865000      4K rw--- ld-2.23.so
00007f0019866000      4K rw---   [ anon ]
00007ffc0cd0a000    136K rw---   [ stack ]
00007ffc0cd4e000     12K r----   [ anon ]
00007ffc0cd51000      8K r-x--   [ anon ]
ffffffffff600000      4K r-x--   [ anon ]
 total            21284K

Note that the smallest size is 4K, that is the page size on my system.

We can see on the rightmost column which files (executables or libraries) were mapped into the address space at which offset. There are also a couple of special regions, such as [stack]. Some of the anonymous regions can be used as a free store/heap. There may be gaps between the mapped ranges of the address space. Trying to access memory in an unmapped range will cause a segfault.

Each of those regions consists of one or more pages. This is important, because pages can have access protections: the executables and libraries provide executable pages for code, read-only pages for constants, and read-write pages for variables. This is a security mechanism to avoid arbitrary data from being executed (though this doesn't matter very much for an interpreter). The pages for the heap and stack will be readable and writeable, but not executable.

An address range may be mapped, but the page for that address might not exist at the moment. Using such an address will trigger a page fault. The operating system can intercept the page fault and add the page. For example, not all pages of the 136K for the stack may exist when the process starts. Instead, the pages are added on demand. Or, a page may have been swapped out to disk. A page fault will cause that page to be loaded back into physical memory.

  • But if segments like heap, stack, etc. are really denoting memory pages, why do you have these terms if you could stick with pages? – so stack Feb 10 '18 at 16:40
  • @asd for the same reason we have terms like int, it raises the level of abstraction. – Aluan Haddad Feb 10 '18 at 16:43
  • Thanks! One more thing: Is it correct that the MMU is responsible for the mapping of virtual addresses and physical addresses? – so stack Feb 10 '18 at 17:07
  • 1
    @asd “stack” and “heap” describe how pages are used. Even if a computer architecture doesn't feature paged memory, we might still use some part of the memory as a “stack”, e.g. in embedded microcontrollers without an OS where physical addresses are used without translation to virtual addresses. Yes, the MMU performs the mapping between virtual and physical addresses. It is typically configured by the operating system. – amon Feb 10 '18 at 19:32
  • @amon wow, now I actually do think that I understand the logical concepts "stack" and "heap"... However, what did you mean by "It is typically configured by the operating system" - is the mapping translation configured by the OS, what should do the mapping, or what is configured by the OS? – so stack Feb 11 '18 at 17:21
4

The concept of pages resides at a lower level than the concept of heap and stack. So yes, you can still talk about the separation of heap and stack. They are build on top of pages.

Memory Segments can either point to physical memory or page-based virtual memory. Object files can also be divided into segments.

As a user of high-level functions like malloc() or the new operator you will not notice either way btw. Unless you access addresses outside of the allocated ranges or exhaust the available space.

1

The text (binary), data, heap, and stack are logical divisions (segments) of the program's memory. Pages are the hardware divisions. The hardware that does the paging also manages the translation from a logical address to a physical address.

There are two models of memory: the logical model of segments and the physical model of pages. And the hardware does the translation between them automatically.

PS: Pages need not be assigned consecutively or in any order. The first page may be from low memory, the next from high, and the next from somewhere in the middle. That's one of the primary advantages of paging: any free page can be assigned to the next logical address.

  • So pages really mean the same as stack, heap, etc.? – so stack Feb 10 '18 at 12:35
  • Yes kind of. It's best to think of them as two separate models with a translation mechanize to relate them. And most of the time, you do not need to worry about the physical model unless you're writing an operating system. – shawnhcorey Feb 10 '18 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.