Memory Layout

  • The stack is the place where all local variables and parameters live for each function. A function’s stack “frame” goes away when the function returns.
  • The stack grows downwards when a new function is called, and shrinks upwards when the function is finished

The Stack

  • Used for function call frames, parameters, local variables
  • LIFO (last-in-first-out): frames are pushed/popped on call/return

Interesting fact: C does not clear out memory when a function’s frame is removed. Instead, it just marks that memory as usable for the next function call. This is more efficient!

A stack overflow is when you use up all stack memory. E.g. a recursive call with too many function calls.

Heap Memory

We need a way to have memory that doesn’t get cleaned up when a function exits.

  • Heap memory persists after function return
  • You must manually free it

use malloc

void *malloc(size_t size);

void *means a pointer to generic memory. You can set another pointer equal to it without any casting.

Function Example

char *create_string(char ch, int n) {
  char *new_str = malloc((sizeof(char) * (n + 1));
  for (int i = 0; i < n; i++) {
    new_str[i] = ch;
  }
  new_str[n] = '\0';
  return new_str;
}

Memory Management Helpers

strdup

char *str = strdup("Hello");
// Allocates and copies string to heap
str[0] = 'h'; // OK

calloc

int *arr = calloc(5, sizeof(int)); // All elements zero-initialized
  • malloc returns a pointer to a certain number of allocated bytes. It doesn’t know or care whether it will be used as an array, a single block of memory, etc.
    It just allocates and returns bytes for you.
  • If an allocation error occurs (e.g. out of heap memory!), malloc will return NULL. This is an important case to check, for robustness.

free() and Memory Leaks

Proper Memory Cleanup

char *bytes = malloc(4);
...
free(bytes); // Free once only!

Common Mistakes

Freeing same memory twice:

char *a = malloc(4);
char *b = a;
free(a);
free(b); // ERROR

Freeing offset address:

free(bytes + 1); // INVALID

realloc

Resizing Memory

char *str = strdup("Hello");
char *add = " world!";
str = realloc(str, strlen(str) + strlen(add) + 1);
strcat(str, add); // Now str = "Hello world!"
free(str);
  • If successful, may move to a new location
  • Old memory is automatically freed
  • Only valid on pointers returned by malloc, calloc, strdup, realloc

Debugging Strategy

  1. Observe the bug
  2. Minimize input
  3. Narrow search space
  4. Use GDB and visualizations
  5. Experiment
  6. Fix and verify

Memory Leaks

  • A memory leak occurs when you lose all references to heap-allocated memory.
  • Doesn’t crash program—but consumes RAM.
  • Tools like Valgrind can detect leaks.
  • Don’t worry during prototyping; fix before submission.

Stack vs. Heap: Summary

FeatureStackHeap
LifetimeAutomatic (function end)Manual (malloc + free)
SpeedFastSlower
SizeLimited (~8MB)Large (until system runs out)
Resizable?NoYes (realloc)
SafetyCompiler type-checksYou manage it