🧠 Foundation β€’ +100 XP

Memory & Pointers

The most critical C concept. Master pointers and memory management to unlock everything else.

⏱️ 90 min🎯 6 sections🧠 3 quizzes

πŸ—ΊοΈ The C Memory Model

β–Ά

In C, memory is just a giant array of bytes. Every variable, string, and struct lives at some address in this array.

Memory: A giant array of bytes
β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”
β”‚ 0  β”‚ 1  β”‚ 2  β”‚ 3  β”‚ 4  β”‚ 5  β”‚ 6  β”‚ 7  β”‚ 8  β”‚... β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”˜
              ↑
         Address 0x0003

int x = 42;   // x might be at address 0x1000
int *p = &x;  // p stores 0x1000
🎯 Key Insight: A pointer is just an integer that happens to represent an address!

πŸ‘‰ Pointer Operations

β–Ά

Two fundamental operations:

& Address-of
int x = 42;
int *p = &x;  // Get address

Returns the memory address where x is stored

* Dereference
*p = 100;     // Set value
int y = *p;   // Get value

Access the value at the address p points to

int x = 42;
int *p = &x;

printf("x = %d\n", x);        // 42
printf("&x = %p\n", &x);      // 0x7fff... (some address)
printf("p = %p\n", p);        // Same address!
printf("*p = %d\n", *p);      // 42 (value at that address)

*p = 100;                     // Modify through pointer
printf("x = %d\n", x);        // 100 (x changed!)

πŸ“š Stack vs Heap

β–Ά
πŸ“š Stack
  • Local variables
  • Function parameters
  • Auto-managed (freed on return)
  • Fast allocation
  • Limited size (~1MB)
πŸ”οΈ Heap
  • malloc/calloc allocations
  • Survives function returns
  • YOU must free it
  • Slower allocation
  • Large (GBs available)
void example() {
    int stack_var = 42;              // Stack (auto-freed)
    int *heap_ptr = malloc(100);     // Heap (you free it)
    
    // When function returns:
    // - stack_var disappears automatically
    // - heap_ptr memory still exists (memory leak if not freed!)
    
    free(heap_ptr);  // Clean up heap
}

πŸ”§ malloc, calloc, realloc, free

β–Ά
// malloc: Allocate uninitialized memory
int *arr = malloc(10 * sizeof(int));  // 10 ints (garbage values)

// calloc: Allocate and zero-initialize
int *arr = calloc(10, sizeof(int));   // 10 ints (all zeros)

// realloc: Resize allocation
arr = realloc(arr, 20 * sizeof(int)); // Now 20 ints

// free: Release memory
free(arr);
arr = NULL;  // Good practice: prevent use-after-free

⚠️ Common Mistakes

Memory Leak: Forgetting to free()
Use After Free: Using pointer after free()
Double Free: Calling free() twice on same pointer

βž• Pointer Arithmetic

β–Ά

Adding to a pointer moves it by element size, not bytes:

int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;         // Points to arr[0]

printf("%d\n", *p);      // 10
printf("%d\n", *(p+1));  // 20  (p+1 moves 4 bytes for int)
printf("%d\n", *(p+2));  // 30

// Array indexing is just pointer arithmetic!
arr[2]  ==  *(arr + 2)  ==  *(p + 2)  // All equal 30
Memory Layout:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   10   β”‚   20   β”‚   30   β”‚   40   β”‚   50   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    ↑         ↑
    p        p+1     (moves 4 bytes, not 1)

🧠 Check Your Understanding

β–Ά
If int x = 42; int *p = &x;, what is *p?
The address of x
42
The address of p
Undefined
Memory allocated with malloc() must be freed by:
The garbage collector
Function return
Calling free()
It's freed automatically
If int *p = arr; and arr starts at address 1000, where is p+2?
1002
1008
1016
2000
← Intro to C Next: Data Structures β†’