Memory Layout
- The stack is the place where all local variables and parameters live for each function. A function’s stack “frame” goes away when the function returns.
- The stack grows downwards when a new function is
called, and shrinks upwards when the function is
finished

The Stack
- Used for function call frames, parameters, local variables
- LIFO (last-in-first-out): frames are pushed/popped on call/return
Interesting fact: C does not clear out memory when a function’s frame is removed. Instead, it just marks that memory as usable for the next function call. This is more efficient!
A stack overflow is when you use up all stack memory. E.g. a recursive call with too many function calls.
Heap Memory
We need a way to have memory that doesn’t get cleaned up when a function exits.
- Heap memory persists after function return
- You must manually free it
use malloc
void *malloc(size_t size);
void *means a pointer to generic memory. You can set another pointer equal to it without any casting.
Function Example
char *create_string(char ch, int n) {
char *new_str = malloc((sizeof(char) * (n + 1));
for (int i = 0; i < n; i++) {
new_str[i] = ch;
}
new_str[n] = '\0';
return new_str;
}
Memory Management Helpers
strdup
char *str = strdup("Hello");
// Allocates and copies string to heap
str[0] = 'h'; // OK
calloc
int *arr = calloc(5, sizeof(int)); // All elements zero-initialized
- malloc returns a pointer to a certain number of allocated bytes. It doesn’t
know or care whether it will be used as an array, a single block of memory, etc.
It just allocates and returns bytes for you. - If an allocation error occurs (e.g. out of heap memory!), malloc will return NULL. This is an important case to check, for robustness.
free() and Memory Leaks
Proper Memory Cleanup
char *bytes = malloc(4);
...
free(bytes); // Free once only!
Common Mistakes
Freeing same memory twice:
char *a = malloc(4);
char *b = a;
free(a);
free(b); // ERROR
Freeing offset address:
free(bytes + 1); // INVALID
realloc
Resizing Memory
char *str = strdup("Hello");
char *add = " world!";
str = realloc(str, strlen(str) + strlen(add) + 1);
strcat(str, add); // Now str = "Hello world!"
free(str);
- If successful, may move to a new location
- Old memory is automatically freed
- Only valid on pointers returned by malloc, calloc, strdup, realloc
Debugging Strategy
- Observe the bug
- Minimize input
- Narrow search space
- Use GDB and visualizations
- Experiment
- Fix and verify
Memory Leaks
- A memory leak occurs when you lose all references to heap-allocated memory.
- Doesn’t crash program—but consumes RAM.
- Tools like Valgrind can detect leaks.
- Don’t worry during prototyping; fix before submission.
Stack vs. Heap: Summary
| Feature | Stack | Heap |
|---|---|---|
| Lifetime | Automatic (function end) | Manual (malloc + free) |
| Speed | Fast | Slower |
| Size | Limited (~8MB) | Large (until system runs out) |
| Resizable? | No | Yes (realloc) |
| Safety | Compiler type-checks | You manage it |