⬅ Previous Next ➡

Memory Layout & Optimization

Memory Layout & Optimization in C++
  • Program Memory Layout explains how a program is placed in memory during execution.
  • Key topics: memory segments, stack vs heap, sizeof, inline expansion, and compilation model.

1) Program Memory Layout (Memory Segments)

  • Typical memory segments of a running program:
    • Text/Code Segment: compiled machine instructions (read-only)
    • Data Segment: initialized global/static variables
    • BSS Segment: uninitialized global/static variables (set to 0)
    • Heap: dynamic memory (new/delete), grows upward
    • Stack: function calls, local variables, grows downward
// Example variables in different segments (concept)
int g = 10;          // Data segment (initialized global)
static int sg = 5;   // Data segment (initialized static)
int u;               // BSS segment (uninitialized global)

int main() {
    int local = 1;        // Stack (local variable)
    int *p = new int(20); // Heap (dynamic)
    delete p;
    return 0;
}

2) Stack vs Heap (Differences)

  • Stack:
    • Automatic memory (allocated/deallocated automatically)
    • Stores local variables + function call frames
    • Very fast, but limited size
    • Risk: stack overflow for deep recursion/large arrays
  • Heap:
    • Manual/managed memory (new/delete, or smart pointers)
    • Used for dynamic objects/arrays
    • Slower than stack, but much larger
    • Risk: memory leaks if delete is missing

3) sizeof Operator

  • sizeof gives size (in bytes) of a type or variable.
  • It is evaluated at compile time for fixed types.
  • Useful for arrays, memory allocation, and portability.
#include <iostream>
using namespace std;

int main() {
    int a = 10;
    double d = 2.5;
    char ch = 'A';

    int arr[5] = {1,2,3,4,5};

    cout << "sizeof(int) = " << sizeof(int) << endl;
    cout << "sizeof(a) = " << sizeof(a) << endl;
    cout << "sizeof(double) = " << sizeof(double) << endl;
    cout << "sizeof(char) = " << sizeof(char) << endl;

    cout << "sizeof(arr) = " << sizeof(arr) << endl;
    cout << "Array length = " << sizeof(arr) / sizeof(arr[0]) << endl;

    return 0;
}

4) Inline Expansion (Optimization Idea)

  • inline suggests compiler to expand function code at the call site.
  • Helps reduce function-call overhead for very small functions.
  • Compiler may ignore inline if function is large or complex.
#include <iostream>
using namespace std;

inline int add(int a, int b) {
    return a + b;
}

int main() {
    cout << "Sum = " << add(10, 20) << endl;
    return 0;
}

5) Compilation Model (How C++ Program Builds)

  • Steps:
    • Preprocessing: handles #include, #define
    • Compilation: converts .cpp to assembly/object code
    • Assembly: produces .o/.obj files
    • Linking: links object files + libraries to create executable
  • Header files are included at preprocessing time, so large headers can slow compilation.
  • Separate compilation:
    • Compile each .cpp into object file
    • Link them together
// Example build commands (g++)
// g++ -c main.cpp      -> main.o
// g++ -c math.cpp      -> math.o
// g++ main.o math.o -o app
// ./app

6) Quick Notes

  • Memory segments: code, data, bss, heap, stack.
  • Stack is fast but limited; heap is flexible but needs careful management.
  • sizeof helps write portable code and find array size.
  • inline may speed up small functions (compiler decides).
  • Compilation model: preprocess → compile → assemble → link.
⬅ Previous Next ➡