Back to Blog

C in 100 Seconds: Memory Leaks | Episode 22

Daryl WongDaryl Wong

Video: C in 100 Seconds: Memory Leaks — malloc Without free | Episode 22 by Taught by Celeste AI - AI Coding Coach

Watch full page →

Memory Leaks — The Cost of Forgetting to Free

C in 100 Seconds, Episode 22


Every malloc needs a matching free. Skip the free and that memory stays allocated for the lifetime of your program. Do it in a loop or a long-running process, and your program slowly eats all available memory.

The Leaky Function

void leaky() {
  int *data = malloc(100 * sizeof(int));
  data[0] = 42;
  printf("Used: %d\n", data[0]);
  // forgot to free!
}

When leaky returns, the local pointer data is destroyed — but the heap memory it pointed to is not. That block is now unreachable. No variable references it. No code can free it. It's leaked.

The Clean Function

void clean() {
  int *data = malloc(100 * sizeof(int));
  data[0] = 42;
  printf("Used: %d\n", data[0]);
  free(data);
}

Same logic, one extra line. free(data) releases the memory before the function returns. The system can reuse that block for future allocations.

How Leaks Compound

A single leak of 400 bytes is harmless. But call leaky() in a loop 10,000 times, and you've leaked 4 MB. In a server running for weeks, leaks accumulate until the system runs out of memory and the process is killed.

Detecting Leaks

On Linux and macOS, you can use Valgrind to detect leaks:

valgrind ./leak

Valgrind tracks every allocation and reports any memory that was never freed. It's one of the most valuable tools for C development.

The Rule

Every malloc, calloc, or realloc must have a corresponding free.

No exceptions. No "the OS will clean it up" (it will, but only when the process exits — not good enough for long-running programs).

Full Code

#include <stdio.h>
#include <stdlib.h>

void leaky() {
  int *data = malloc(100 * sizeof(int));
  data[0] = 42;
  printf("Used: %d\n", data[0]);
  // forgot to free!
}

void clean() {
  int *data = malloc(100 * sizeof(int));
  data[0] = 42;
  printf("Used: %d\n", data[0]);
  free(data);
}

int main() {
  printf("Leaky function:\n");
  leaky();

  printf("\nClean function:\n");
  clean();

  return 0;
}

Compile and Run

gcc leak.c -o leak
./leak

Next episode: Continue exploring C — more data structures and patterns ahead.

Student code: github.com/GoCelesteAI/c-in-100-seconds/episode22