1. Memory in a C Program
When a C program runs, memory is typically divided into:
| Memory Region |
Purpose |
Managed By |
| Code/Text |
Stores program instructions |
Compiler/OS |
| Global/Static |
Stores global and static variables |
Compiler/OS |
| Stack |
Stores function call frames, local variables |
Automatically managed (LIFO) |
| Heap |
Stores dynamically allocated memory |
You (via malloc, free, etc.) |
2. Static vs Dynamic Memory
-
Static: Known at compile time (global variables, static variables, fixed-size arrays).
-
Automatic: Created on the stack, freed when function exits.
-
Dynamic: Allocated at runtime on the heap, must be manually freed.
3. Dynamic Memory Allocation Functions
From <stdlib.h>:
| Function |
Purpose |
Notes |
malloc(size) |
Allocates size bytes |
Contents uninitialized |
calloc(n, size) |
Allocates n * size bytes |
Initializes to zero |
realloc(ptr, new_size) |
Changes size of allocated memory |
May move memory |
free(ptr) |
Frees allocated memory |
ptr must be from malloc, calloc, or realloc |
Example:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = malloc(5 * sizeof(int)); // allocate for 5 ints
if (!arr) {
printf("Memory allocation failed\n");
return 1;
}
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
}
arr = realloc(arr, 10 * sizeof(int)); // resize
if (!arr) {
printf("Reallocation failed\n");
return 1;
}
free(arr); // release memory
return 0;
}
4. malloc vs calloc
-
malloc: Faster, memory not initialized
-
calloc: Slower, memory is initialized to zero
Example:
int *p = malloc(5 * sizeof(int)); // garbage values
int *q = calloc(5, sizeof(int)); // all values are 0
5. Common Memory Issues in C
-
Memory leaks — forgetting to free() allocated memory
-
Dangling pointers — using a pointer after freeing it
-
Double free — freeing the same pointer twice
-
Buffer overflow — writing beyond allocated size
-
Uninitialized memory usage — reading before assigning
6. Best Practices
-
Always check if malloc/calloc/realloc returns NULL
-
free() everything you allocate before program exits
-
Set pointers to NULL after free() to avoid dangling pointers
-
Use sizeof(*ptr) instead of sizeof(type) to avoid type mismatches
-
Avoid memory allocation inside tight loops unless necessary
7. Visual Diagram
Imagine this code:
int x = 10; // stack
int *p = malloc(sizeof(int)); // heap
*p = 20;
Memory layout:
Stack:
[ x=10 ] [ p = 0x6000 ]
Heap:
0x6000 -> [ 20 ]
8. Detecting Memory Problems
Tools like:
Do you want me to make that?