C++ Stack vs Heap
Understand stack and heap memory allocation with interactive visualizations.
Best viewed on desktop for optimal interactive experience
Stack vs Heap Memory
Understanding where and how memory is allocated is crucial for writing efficient C++ programs. See the differences in action:
Stack vs Heap Memory
Stack (LIFO)
High Address ↑
main()
32 bytes
int x = 42
4 bytes
Low Address ↓ (grows down)
Stack Usage:36 bytes
Automatic deallocation on scope exit
Heap (Dynamic)
Low Address ↓ (grows up)
int* p = new int[10]
40 bytes
High Address ↑
Heap Usage:40 bytes
Fragmentation:0.0%
Aspect | Stack | Heap |
---|---|---|
Allocation | Automatic | Manual (new/malloc) |
Deallocation | Automatic | Manual (delete/free) |
Speed | Very Fast | Slower |
Size Limit | Limited (~8MB) | System Memory |
Fragmentation | None | Possible |
Stack Memory
Characteristics
- Automatic: Managed by compiler
- Fast: Simple pointer arithmetic
- Limited: ~8MB default size
- LIFO: Last In, First Out
- Scope-based: Automatic cleanup
Stack Allocation
void function() { int local = 42; // Stack char buffer[256]; // Stack MyClass obj; // Stack } // All automatically deallocated
Stack Frame
Each function call creates a frame:
[Return Address] [Previous Frame Pointer] [Local Variables] [Function Parameters]
Heap Memory
Characteristics
- Manual: You control lifetime
- Slower: Allocation overhead
- Large: System memory limit
- Fragmented: Can have gaps
- Flexible: Any size, any time
Heap Allocation
// C++ style int* ptr = new int(42); int* arr = new int[100]; delete ptr; delete[] arr; // C style int* ptr = (int*)malloc(sizeof(int)); free(ptr); // Smart pointers (recommended) auto ptr = std::make_unique<int>(42); auto arr = std::make_shared<int[]>(100);
Memory Issues
Stack Overflow
// Recursive without base case void infinite() { infinite(); } // Large local arrays void bad() { int huge[10000000]; // Too big! }
Memory Leak
void leak() { int* p = new int(42); // Missing: delete p; } // Memory leaked!
Dangling Pointer
int* dangling() { int local = 42; return &local; // Bad! Returns stack address }
Comparison Table
Aspect | Stack | Heap |
---|---|---|
Speed | Very Fast | Slower |
Size | Limited (~8MB) | System Memory |
Management | Automatic | Manual |
Fragmentation | None | Possible |
Thread Safety | Yes (per thread) | No (needs sync) |
Allocation | Compile-time size | Runtime size |
Best Practices
- Prefer stack allocation when possible
- Use smart pointers for heap objects
- Follow RAII principles
- Avoid large stack arrays (use std::vector)
- Match new/delete and new[]/delete[]
- Check for null before dereferencing
- Use tools like valgrind, sanitizers
Modern C++ Approach
// Avoid raw pointers // Bad int* p = new int(42); // Good auto p = std::make_unique<int>(42); // Container instead of array // Bad int* arr = new int[size]; // Good std::vector<int> arr(size);
Next Steps
- Master Smart Pointers
- Learn RAII Patterns
- Explore Memory Layout