Show Lecture.MemorySegments as a slide show.
CS253 Memory Segments
Mnemosyne, goddess of memory
Segments
There are several “segments”, or areas of memory, where parts
of your program live, in a typical computer architecture:
- Text: executable code (machine instructions)
- Data: initialized static or global data
- BSS: uninitialized static or global data
- Stack: local variables
- Heap: allocated via malloc() or new
Text: executable code
- The text segment contains executable code (cpu instructions).
Don’t obsess over the name—it’s not text strings.
- On today’s computers, text is marked as read-only and executable,
where other segments are not.
- This prevents a berserk program from overwriting
its own instructions via a wild pointer.
- This allows sharing. When several bashes are running, we only need
one copy of bash’s executable code in RAM. This saves memory and
increases the chance of instructions being in cache.
- The text segment is stored in the
a.out
file.
- That’s the executable machine language program on the disk,
called
a.out
(assembler output)
by default by g++.
Data: initialized non-dynamic non-stack data
- The data segment contains initialized non-dynamic data.
- Initialized globals live in the data segment.
- Initializer local variables also, if declared static.
- It is read-write at run-time—programs may alter their variables.
- The data segment is stored in the
a.out
file.
BSS: uninitialized static data
Brain Salad Surgery
- The BSS segment contains “uninitialized” static data.
- It is zero-initialized at initial load of the program.
- It is read-write at run-time—programs may alter their variables.
- BSS has no associated data, so the
a.out
file only has to know how
big the BSS segment is, lay out that much space at run-time, and clear
it. Almost no space required in a.out
.
- Clever compilers put zero-initialized static variables in BSS.
- The origin of the name is unclear—perhaps the assembler pseudo-op
Begin Section started by Symbol.
Stack: local variables
- The stack segment contains local variables
- Declared at function scope or even smaller, e.g., an if block.
- If an initial value is given, it is assigned at run-time.
Otherwise, the value is indeterminate.
Seriously: it’s unknown.
- It contains whatever value the memory had before that.
- It might be initially zero due to the OS clearing memory.
- It is read-write at run-time—programs may alter their local variables.
- It is not stored in the
a.out
at all, except implicitly,
in subroutine preamble code.
Heap: allocated via new
- The heap segment is contains uninitialized dynamic variables.
- It is read-write at run-time—programs may alter their local variables.
- It is not stored in the
a.out
at all.
- Traditionally, free/allocated dynamic memory is kept track of via a
heap data structure,
hence the name.
Example
int b1[3], d1=45;
const int t1 = 299'792'458;
int main() {
static double b2 = 0.0, d2 = 2.718281828;
int s1 = 10, *s2 = new int[s1];
vector<int> s3 = {123,456,789};
map<const void *, string> stuff = {
{&s1, "s1"}, {&t1, "t1"},
{&s2, "s2"}, {&b1, "b1"}, {&d1, "d1"},
{&s3, "s3"}, {&b2, "b2"}, {&d2, "d2"},
{&s2[0], "s2[0]"}, {&s3[0], "s3[0]"},
{&cout, "cout"}, {(void *) exit, "exit"},
};
for (auto [addr, name] : stuff)
cout << setw(14) << addr << ' ' << name << '\n';
delete[] s2;
}
0x401680 exit
0x404608 t1
0x607170 d1
0x607178 d2
0x607180 cout
0x607298 b1
0x6072a8 b2
0x21ab2b0 s2[0]
0x21ab2e0 s3[0]
0x7fff564772b0 s3
0x7fff564772d0 s2
0x7fff564772dc s1
What is in each memory segment?
Summary
Text | Data | BSS | Stack | Heap |
instruction/const | initialized global | uninitialized global | local var | dynamic memory |
allocated at compile-time | allocated at run-time |
read-only | read-write |
occupies space in a.out | no space in a.out |