I'm currently learning about operating systems and I learned that the stack is located between the kernel and the heap. What confuses me is that in most implementations, since the stack tends to grow downwards while the heap grows to higher memory addresses what is stopping the stack from growing into the heap? If it were possible what would happen if it did grow into the heap?
The much-simplified view of memory traditionally looks something like this:
===================
| Operating System | High memory
===================
| Your program |
| --------------- |
| | Process stack | |
| --------------- | Transient program area
| | Process heap | |
| --------------- |
| | Program code | |
| --------------- |
===================
| Operating system | Low memory
===================
As you pointed out, the process stack starts just below the operating system code, and grows downward. The process heap, on the other hand, starts just above the fixed program code, and grows upward.
In the early days of PC operating systems that really was the physical layout of a program in memory. The CP/M operating system, for example, reserved the first 256 bytes of memory for some operating system bootstrap code, and the rest of the necessary operating system services occupied the high memory area. Programs started at address 0x0100, and could use all the memory between there and the start of the operating system code at the top. MS-DOS was very similar.
There were no guardrails to prevent what you mentioned from happening: a program would allocate so much space on the stack that it overwrote memory that was allocated on the heap. Or, the program would allocate heap memory that overwrote the processor stack. When either of those things happened, the program would crash. In some cases, the operating system would crash, too. Of course, because only one program could be running at a time, that wasn't a huge deal: just reboot the machine and try again.
Modern computers have much more advanced memory layouts, and that conceptual picture no longer holds true. Operating systems today can do a much better job of enforcing memory access restrictions. A process, for example, is assigned a fixed segment for its stack (typically on the order of 1 megabyte). If the program tries to use more stack space than is allocated, the memory manager won't allow it. The program will crash with an access violation. And the program's heap can't grow into the memory allocated to the stack for the same reason.
This is not necessarily correct:
I'm currently learning about operating systems and I learned that the stack is located between the kernel and the heap.
Stack and heaps are just memory. They are indistinguishable except how they are used. There can be multiple heaps and multiple stacks in the address space.
A heap could not grow into the stack and vice versa. The operating system will not allow a heap to reallocate memory already allocated for a stack.
One could access memory beyond the end of a stack that, in theory, could be part of a a heap. Some operating systems put inaccessible guards at the end of stacks.
© 2022 - 2024 — McMap. All rights reserved.
alloca()
or VLA. And especially since thread stacks are mixed in with other dynamic allocations. The x86 disassembly for C code generates: orq $0x0, %(rsp) has more info about modern mechanisms to harden against such bugs, also Linux process stack overrun by local variables (stack guarding) – Greek