The Memory Model: Stack, Heap and Static
Rocket Run keeps a few numbers for a moment, one high score for the whole session, and a level full of asteroids whose count is only known after the level file loads. These three needs map onto three kinds of storage, and knowing which one an object uses tells you exactly when it disappears.
The rule
Braces end locals, owners end heap objects, program exit ends statics.
Every object occupies some bytes, has an address, and has a storage duration:
- Automatic (usually called the stack): ordinary local variables. Created when the line runs, destroyed at the closing
}of their scope. Fast and automatic. - Dynamic (usually called the heap): objects you create at run time, whose size or lifetime is not known in advance. They live until their owner releases them.
- Static: globals and
staticlocals. Set up once, and they last until the program ends.
void playLevel(int asteroidCount) {
int lives = 3; // automatic
static int highScore = 0; // static: kept between calls
std::vector<Asteroid> rocks(asteroidCount); // the vector's elements live on the heap
auto boss = std::make_unique<Boss>(); // heap object, owned by boss
} // lives, rocks and boss end here, and rocks and boss free their heap memoryIn modern C++ you rarely touch the heap by hand. std::vector, std::string and std::make_unique allocate for you and free the memory when they themselves are destroyed. The raw version, new with a matching delete, is easy to get wrong: forget the delete and the memory leaks.
You can ask any type how many bytes it takes with sizeof. sizeof(char) is always 1; most other sizes depend on the platform.
The shortcut
For any object, ask one question: who decides when it dies?
int lives inside playLevel
Its closing brace decides. Automatic storage.
The trap is keeping the address of an automatic object after its scope has ended. The memory is reused, and using that address is undefined behaviour.
Drills
Answer fast — trust the rule.
Where does int lives = 3; inside a function live?
How long does static int highScore = 0; inside a function last?
When is heap storage the right choice?
What is sizeof(char)?
A function returns the address of one of its local int variables. What is wrong?
Remember
- Braces end locals, owners end heap objects, program exit ends statics.
- Shortcut: ask who decides when the object dies.
- Trap: never keep the address of a local after its scope ends.
