0

When a C++ program is started there are a few memory segments/areas allocated:

  1. For the program itself and the used libraries. The size of the program and its libraries is known in advance.

  2. For global variables and for constants. Similarly, the sizes of these memory segments are known at compile-time.

  3. However with the stack and heap are in a different situation. The sizes of these seem to not be fixed.

I am by no means a specialist in the inner workings of C++ so please consider correcting any wrong assumptions I make as part of the question.

For the sake of this question let's assume we are running on Windows10 and using Visual C++ (please tell me if the answer can differ on any other major platforms).

My questions are:

  1. Is the heap dynamic in size? (i.e. can the size of the heap change during run-time?) I would assume it is since you can always malloc more space if you need to.

  2. Is the stack dynamic in size? This is trickier since we know what functions will be called and what/how many local variables they will have but what makes me think it might be dynamic in size is that things like recursion, lambdas function pointers, reading values from other files can make it impossible to tell how many times a function will be called.

  3. If the answer to the 2 above questions is "yes" then how are these memory zones places in the physical memory? Are they contiguous with one another and with the program memory? (i.e. is the actual program from address 0 to address x, the stack from address x to x+k and the heap from (x+k) to (x+k)+p?)

  4. If the answer to 3. is "yes" then what happens when a memory area "in the middle" like the stack needs to be resized?

This is purely an educational question. In the answer please correct any wrong assumptions I have made.

Rares Dima
  • 1,575
  • 1
  • 15
  • 38
  • Stack is usually defaulted to about 1M and can be changed using linking options. The max heap is usually all available memory. When you add Virtual Addressing and process page tables into the question of memory layout the answer is all over the place in physical memory. No compiler I am familiar with tries to resize the stack. When the size of the stack is exceeded you usually get a hard fault (segment exception). – Richard Critten May 27 '21 at 08:22
  • I'm hardly an expert but answer go 1 yes, 2 yes (but there's a smaller limit here), 3 not exactly. Even if you think of pointers as "numbers" they're not, memory is not indexed from 0 to the amount of memory your computer has. So 2 pointers you have might not be comparable if they weren't allocated together (say 2 items in a long array). And in general you can never do arithmetic between pointers from heap vs stack. All the pointers you have are somewhat fake and the OS/cpu knows where the thing you're looking for is (cache/ram/paged on disk). So problem 4 doesn't exist. – al3c May 27 '21 at 08:23
  • You may google for "virtual address space" to get some sources. In short, the virtual address space of a process is split into different parts such as a data segment, stack, and heap. Pages from these segments are then mapped to the physical memory. Contiguous addresses across pages boundaries in the virtual address space doesn't mean they are placed next to each other in the physical memory. If a process needs more memory (in its virtual address space), it asks a kernel for it (such as by `sbrk` or `mmap` syscalls in Linux) and the kernel takes care of their mapping to RAM. – Daniel Langr May 27 '21 at 08:32
  • On 64-bit machines virtual address space is so vast that plenty of it can be reserved for the stack to eventually grow into without any problem. – EOF May 27 '21 at 08:36
  • Possibly relevant: [C/C++ maximum stack size of program](https://stackoverflow.com/q/1825964/580083). – Daniel Langr May 27 '21 at 08:42
  • *"The size of the program and its libraries is known in advance"* This statement is a bit oversimplified. Be aware of the fact that in case of shared libraries can easily make a program violate the assumption of "all logic can be put into one place in memory"; this is even without considering the fact that you can load dlls dynamically at runtime... – fabian May 27 '21 at 08:45
  • Also note that (at least some immutable) parts of shared libraries may be at runtime shared by multiple processes, which allows them to be placed in RAM only once. The question is then whether you want to consider such memory as being a part of a process memory or not. – Daniel Langr May 27 '21 at 09:11

0 Answers0