What is the Stack
beginner
c++11
memory
All variables in C++ use a portion of the memory of your computer.
C++ has two basic forms of memory: the stack and the heap.
The stack is where local variables are stored in memory.
Local here means “in the current scope” and a scope is defined as the code between curly braces ({}
).
Every time a new scope is created C++ uses a portion of the stack to store that scope’s local variables and if it’s a function its parameters and return value.
Because C++ has pointers we can print the addresses of stack variables and confirm for ourselves they are using different pieces of memory.
Here’s an example of scopes and stack variables:
#include <iostream> void foo(int a) { std::cout << " foo() Scope\n"; int b = 4; std::cout << " a: " << a << ", &a: " << &a << "\n"; std::cout << " b: " << a << ", &b: " << &b << "\n"; std::cout << " leaving foo() Scope\n"; } int main() { std::cout << "Main Scope\n"; int a = 10; std::cout << "a: " << a << ", &a: " << &a << "\n"; { std::cout << " First Inner Scope\n"; int b = 20; std::cout << " a: " << a << ", &a: " << &a << "\n"; std::cout << " b: " << b << ", &b: " << &b << "\n"; { std::cout << " Second Inner Scope\n"; int c = 30; std::cout << " a: " << a << ", &a: " << &a << "\n"; std::cout << " b: " << b << ", &b: " << &b << "\n"; std::cout << " c: " << a << ", &c: " << &c << "\n"; foo(a); std::cout << " Leaving Second Inner Scope\n"; } std::cout << " a: " << a << ", &a: " << &a << "\n"; std::cout << " b: " << b << ", &b: " << &b << "\n"; std::cout << " Leaving First Inner Scope\n"; } std::cout << "a: " << a << ", &a: " << &a << "\n"; std::cout << "Leaving Main Scope\n"; }
Main Scope a: 10, &a: 0x7ff7b34465cc First Inner Scope a: 10, &a: 0x7ff7b34465cc b: 20, &b: 0x7ff7b34465c8 Second Inner Scope a: 10, &a: 0x7ff7b34465cc b: 20, &b: 0x7ff7b34465c8 c: 10, &c: 0x7ff7b34465c4 foo() Scope a: 10, &a: 0x7ff7b34465ac b: 10, &b: 0x7ff7b34465a8 leaving foo() Scope Leaving Second Inner Scope a: 10, &a: 0x7ff7b34465cc b: 20, &b: 0x7ff7b34465c8 Leaving First Inner Scope a: 10, &a: 0x7ff7b34465cc Leaving Main Scope
Automatic Memory Management
Explicit management of the stack is not necessary in your program and is automatic in C++. Automatic memory management of scopes and local variables is one of the many things your compiler is doing for you when your code is compiled into a complete program. If you’re familiar with destructors you’ll remember that C++ always calls object destructors when that object is leaving the scope it’s in. That’s because the stack memory of that object is about to be reclaimed and reused for the next scope and so the object must be cleaned up. Here’s an example:
#include <iostream> class Talker { public: explicit Talker(std::string name) : name_(std::move(name)) { std::cout << name_ << " here.\n"; } ~Talker() { std::cout << name_ << ", signing off.\n"; } private: std::string name_; }; int main() { std::cout << "Main Scope\n"; Talker jose("Jose"); std::cout << "&jose: " << &jose << "\n"; { std::cout << " First Inner Scope\n"; Talker nushi(" Nushi"); std::cout << " &nushi: " << &nushi<< "\n"; std::cout << " Leaving First Inner Scope\n"; } std::cout << "Leaving Main Scope\n"; }
Main Scope Jose here. &jose: 0x7ff7bc8575b8 First Inner Scope Nushi here. &nushi: 0x7ff7bc857578 Leaving First Inner Scope Nushi, signing off. Leaving Main Scope Jose, signing off.
Variable Shadows
When new scopes are created variables from outer scopes can still be used, but they can also be shadowed meaning their names can be reused.
#include <iostream> int main() { int a = 4; std::cout << "a: " << a << ", &a: " << &a << "\n"; { // Assign to the same "a" from outer scope a = 8; std::cout << " a: " << a << ", &a: " << &a << "\n"; { // *Shadow* the outer scope's "a", create a new "a" int a = 12; std::cout << " a: " << a << ", &a: " << &a << "\n"; } std::cout << " a: " << a << ", &a: " << &a << "\n"; } std::cout << "a: " << a << ", &a: " << &a << "\n"; }
a: 4, &a: 0x7ff7b03b95cc a: 8, &a: 0x7ff7b03b95cc a: 12, &a: 0x7ff7b03b95c8 a: 8, &a: 0x7ff7b03b95cc a: 8, &a: 0x7ff7b03b95cc