C Memory Leaks
In this page:
type *ptr = malloc(sizeof(type)); // allocate on the heap
// ... use ptr ...
free(ptr); // release it, or the memory leaks
What is a memory leak?
Unlike a crash, a leak doesn't cause immediate visible failure -- the program keeps running, but its memory footprint grows over time, which is especially dangerous in long-running programs like servers that might run for weeks or months.
Example: What is a memory leak?
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
// Allocate memory on the heap
int *ptr = malloc(sizeof(int));
*ptr = 5;
// Print formatted text to the screen
printf("%d", *ptr);
// Release the heap memory so it can be reused
free(ptr);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Common causes of memory leaks
A particularly sneaky cause is reassigning a pointer variable to a new malloc() result before freeing what it previously pointed to -- the old block becomes unreachable the instant the pointer is overwritten, with no error or warning.
Example: Common causes of memory leaks
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
// Allocate memory on the heap
int *ptr = malloc(sizeof(int));
// Release the heap memory so it can be reused
free(ptr);
// Allocate memory on the heap
ptr = malloc(sizeof(int));
*ptr = 5;
// Print formatted text to the screen
printf("%d", *ptr);
// Release the heap memory so it can be reused
free(ptr);
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Detecting memory leaks
Dedicated tools like Valgrind can run your program and report exactly which allocations were never freed, along with the line of code that allocated them -- manual tracing works for small programs but doesn't scale well to large codebases.
Example: Detecting memory leaks
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
// Allocate memory on the heap
int *ptr = malloc(sizeof(int));
*ptr = 5;
// Print formatted text to the screen
printf("Run with Valgrind to detect unfreed allocations");
// Release the heap memory so it can be reused
free(ptr);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Fixing memory leaks in loops
A loop that calls malloc() on each iteration but only frees outside the loop (or not at all) can exhaust available memory surprisingly quickly, since each iteration adds another leaked block on top of the last.
Example: Fixing memory leaks in loops
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
// Loop: repeat while the condition holds
for (int i = 0; i < 3; i++) {
// Allocate memory on the heap
int *ptr = malloc(sizeof(int));
*ptr = i;
// Release the heap memory so it can be reused
free(ptr);
}
// Print formatted text to the screen
printf("Freed each iteration's allocation");
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Memory management strategies
In larger codebases, it's common to document (in a comment or the function's name itself) whether a function transfers ownership of returned memory to the caller, since ambiguity about who's responsible for freeing something is a leading cause of leaks.
Example: Memory management strategies
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
int* createValue() {
// Allocate memory on the heap
int *ptr = malloc(sizeof(int));
*ptr = 5;
// Send ptr back to the caller
return ptr;
}
// Program execution starts in main()
int main() {
int *value = createValue();
// Print formatted text to the screen
printf("%d", *value);
// Release the heap memory so it can be reused
free(value);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
- Reassigning a pointer to a new allocation before freeing the old one, which loses the only reference.
- Returning early from a function before reaching the
freecall. - Allocating memory inside a loop without freeing it each time.
- Dynamic memory is requested at run time with
malloc()andcalloc(), and resized withrealloc(). - Memory you no longer need must be released with
free(), otherwise it leaks. - The same allocation approach works for structs, and you must be careful when accessing allocated memory.
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: