Dynamic Memory with malloc and free
Allocating heap memory at runtime, and the leak/dangling-pointer risks of managing it yourself.
What you'll learn
- Allocate heap memory with malloc and check whether it succeeded
- Release allocated memory with free once it's no longer needed
- Explain what a memory leak and a dangling pointer are, and how to avoid each
Explanation
So far, every variable's size has been fixed and known at compile time. malloc (from <stdlib.h>) lets a program request a block of memory at runtime, from a region called the heap: int *arr = malloc(3 * sizeof(int)); requests enough space for 3 ints and returns a pointer to the start of that block. malloc can fail (e.g. if the system is out of memory), returning NULL in that case -- production code should always check for this before using the returned pointer.
Memory obtained from malloc is not automatically cleaned up when it goes out of scope, unlike a local variable's stack memory. You must explicitly release it with free(arr); once you're done with it. Forgetting to call free on memory you no longer use is a memory leak -- the memory stays reserved for the rest of the program's run, unusable by anything else, even though nothing in your program can reach it anymore.
There's a danger on the other side too: a dangling pointer is a pointer that still holds the address of memory that has already been freed. Using it after the free call (reading, writing, or calling free on it a second time) is undefined behavior -- it might appear to work, corrupt unrelated data, or crash, unpredictably. A common defensive habit is setting a pointer to NULL immediately after freeing it (free(arr); arr = NULL;), so any accidental later use fails predictably and safely rather than silently corrupting memory.
Guided lab
Guided edit: Adding free() to a heap allocation
Follow each step to see how adding free() changes this program's resource hygiene.
Step 1 of 2
Start with a heap allocation that's used but never freed. This is a memory leak -- a real bug, even though it doesn't change this program's printed output, since the program exits immediately afterward anyway.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *arr = malloc(3 * sizeof(int));
if (arr == NULL) {
printf("Allocation failed\n");
return 1;
}
for (int i = 0; i < 3; i++) {
arr[i] = (i + 1) * 10;
}
int sum = 0;
for (int i = 0; i < 3; i++) {
sum += arr[i];
}
printf("Sum: %d\n", sum);
return 0;
}Stuck? Get a hint.
Common mistakes
- Forgetting to call free() on heap memory once it's no longer needed, causing a memory leak.
- Using a pointer after calling free() on it (a dangling pointer), or calling free() on the same pointer twice.
- Not checking whether malloc returned NULL before using the pointer it returned, assuming allocation always succeeds.
Knowledge check
Takeaway
Every successful malloc needs a matching free once the memory is no longer needed -- and setting a pointer to NULL right after freeing it helps catch accidental reuse.
Summary
malloc requests heap memory at runtime and can fail (returning NULL); free releases it explicitly, since heap memory isn't cleaned up automatically -- forgetting free leaks memory, and using freed memory creates a dangling pointer.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.