C++ Stack vs Heap

6 min

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%
AspectStackHeap
AllocationAutomaticManual (new/malloc)
DeallocationAutomaticManual (delete/free)
SpeedVery FastSlower
Size LimitLimited (~8MB)System Memory
FragmentationNonePossible

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

AspectStackHeap
SpeedVery FastSlower
SizeLimited (~8MB)System Memory
ManagementAutomaticManual
FragmentationNonePossible
Thread SafetyYes (per thread)No (needs sync)
AllocationCompile-time sizeRuntime size

Best Practices

  1. Prefer stack allocation when possible
  2. Use smart pointers for heap objects
  3. Follow RAII principles
  4. Avoid large stack arrays (use std::vector)
  5. Match new/delete and new[]/delete[]
  6. Check for null before dereferencing
  7. 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

If you found this explanation helpful, consider sharing it with others.

Mastodon