Memory Management
What Python does for you automatically
Introduction
In this lesson, you'll learn about memory management in C. Coming from Python, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In Python, you're familiar with what python does for you automatically.
C has its own approach to what python does for you automatically, which we'll explore step by step.
The C Way
Let's see how C handles this concept. Here's a typical example:
#include <stdlib.h>
#include <string.h>
/* Stack — automatic */
int x = 42; /* freed when function returns */
/* Heap — manual */
int *nums = malloc(1000 * sizeof(int));
char *text = malloc(600 + 1);
typedef struct { char *key; int *values; int n; } Data;
Data *make_data() {
Data *d = malloc(sizeof(Data));
d->key = strdup("key");
d->values = malloc(3 * sizeof(int));
d->values[0]=1; d->values[1]=2; d->values[2]=3;
d->n = 3;
return d; /* caller must free! */
}
void free_data(Data *d) {
free(d->key);
free(d->values);
free(d);
}
Data *result = make_data();
/* use result */
free_data(result); /* caller is responsible */Comparing to Python
Here's how you might have written similar code in Python:
# Python handles all memory automatically
nums = [0] * 1000 # allocated
text = "hello " * 100 # allocated
def make_data():
data = {"key": [1, 2, 3]} # allocated
return data # returned safely
result = make_data()
# When result goes out of scope, GC frees everything
# No dangling references possible in PythonYou may be used to different syntax or behavior.
Python GC frees memory automatically; C requires explicit free for every malloc
You may be used to different syntax or behavior.
Python has no dangling pointers; C's freed memory can be accidentally accessed
You may be used to different syntax or behavior.
Python reference counting handles cycles; C must manually break them
You may be used to different syntax or behavior.
C memory leaks cause long-running programs to consume ever-increasing RAM
Step-by-Step Breakdown
1. Every malloc Needs a free
Unlike Python where the GC tracks and frees objects, C requires an explicit free() for every malloc() — or you have a memory leak.
nums = [0] * 1000 # GC handles cleanupint *nums = malloc(1000 * sizeof(int));
// ... use ...
free(nums); // mandatory!2. Ownership Convention
C programs must define who is responsible for freeing memory. Common convention: the caller frees what the callee allocates.
3. Stack vs Heap
Local variables (stack) are freed automatically when the function returns. Heap (malloc) persists until explicitly freed.
void example() {
int stack[100]; // freed on return — OK to use
int *heap = malloc(100 * sizeof(int)); // persists
// ...
free(heap); // must free before return
}Common Mistakes
When coming from Python, developers often make these mistakes:
- Python GC frees memory automatically; C requires explicit free for every malloc
- Python has no dangling pointers; C's freed memory can be accidentally accessed
- Python reference counting handles cycles; C must manually break them
Key Takeaways
- Every malloc needs exactly one free
- Memory leaks: forget free → RAM grows forever
- Stack auto-frees; heap is manual
- Set pointers to NULL after freeing