This reading is optional, but if you are curious about more details of how C programs typically allocate memory, this is a start. Keep in mind that this is a typical layout - compiler writers may deviate in how they assign memory to different types of instructions found in a C program. Also, as a security feature, memory addresses of variables are generally randomized.
When a program runs, the operating system assigns space in memory for the whole program, including the executable instructions generated by the compiler's translation. As the program runs, the operating system manages the space assigned to the program and generally will not allow a program to try to use any memory spaces outside of its assigned boundaries. (Accidentally or deliberately trying to work out of bounds should result in an error such as a "segmentation fault".)
Most commonly, the sections of a program are layed out in this order:
| High address | command-line arguments |
|
| Stack (grows downward) |
variables from main() and other functions go here | |
| Heap (grows upward) |
dynamically allocated memory using malloc() | |
| Uninitialized data segment | global variables and static variables that are not initialized by the programmer or that are initialized to zero (0) | |
| Initialized data segment | global variables and static variables that are initialized to a value other than zero (0) | |
| Low address | Text segment | Executable code of main() and other functions (read only) |
The stack and both data segments may be further divided into read only sections and modifiable sections.
In some compilers, string literals (such as mystring = "This is an unchangeable string!") may be stored in the text segment. Or they might be considered a static variable and stored in the initialized data segment.
This reading is a simplification of an article by Narendra Kangralkar at Geeks for Geeks.