Dynamic memory: malloc and free
Ask for memory at run time when you don't know sizes in advance - and give it back when you are done.
- Describe the difference between the stack and the heap
- Allocate and release memory with
mallocandfree - Avoid leaks, double frees and use-after-free bugs
Every array so far has had a size fixed when you wrote the code. Real programs often find out how much data there is only while running - a file of unknown length, a user-chosen number of items. For that, C lets you request memory from the heap at run time.
Stack and heap
- Stack: where local variables live. Allocation is automatic and fast, and the memory disappears when the function returns. Its size is limited (often a few megabytes).
- Heap: a large pool you manage by hand. You ask for bytes with
malloc, and they stay yours - even after the function returns - until you hand them back withfree.
malloc and free
1#include <stdio.h>
2#include <stdlib.h>
3
4int main(void) {
5 size_t count = 5;
6 int *numbers = malloc(count * sizeof *numbers);
7 if (numbers == NULL) {
8 fprintf(stderr, "Out of memory\n");
9 return 1;
10 }
11
12 for (size_t i = 0; i < count; i++) {
13 numbers[i] = (int)(i * 10);
14 }
15 for (size_t i = 0; i < count; i++) {
16 printf("%d ", numbers[i]);
17 }
18 printf("\n");
19
20 free(numbers);
21 numbers = NULL;
22 return 0;
23}0 10 20 30 40
The pattern to memorize:
malloc(count * sizeof *pointer)asks for enough bytes. Usingsizeof *numbers(the size of what the pointer points at) stays correct even if you later change the element type.- Check for
NULL.mallocreturnsNULLwhen it cannot give you the memory. - Use it like an array.
numbers[i]works exactly as before. freeit exactly once when you are finished, then set the pointer toNULLso an accidental second use fails loudly instead of silently.
malloc does not clear the memory - it contains garbage. calloc(count, size) allocates and zeroes it. realloc(pointer, new_size) grows or shrinks an allocation (possibly moving it).
The three classic memory bugs
| Bug | What happens | Prevention |
| --- | --- | --- |
| Memory leak | You lose the last pointer to memory without freeing it. It stays allocated until the program exits. | Every malloc gets a matching free on every path out. |
| Use after free | You read or write memory after freeing it. It may have been reused for something else. | Set pointers to NULL after free. |
| Double free | You free the same memory twice, corrupting the allocator. | Free once; free(NULL) is a safe no-op, so NULL-ing helps here too. |
Returning memory from a function
Unlike a local array, heap memory outlives the function that allocated it - so a function can safely return it. The rule that comes with it: document who is responsible for calling free. Usually, "the caller frees what they receive".
1#include <stdio.h>
2#include <stdlib.h>
3
4// Returns 1..n in a new array. The caller must free() it.
5int *make_range(size_t n) {
6 int *range = malloc(n * sizeof *range);
7 if (range == NULL) {
8 return NULL;
9 }
10 for (size_t i = 0; i < n; i++) {
11 range[i] = (int)i + 1;
12 }
13 return range;
14}
15
16int main(void) {
17 int *numbers = make_range(4);
18 if (numbers == NULL) {
19 return 1;
20 }
21 printf("%d %d %d %d\n", numbers[0], numbers[1], numbers[2], numbers[3]);
22 free(numbers);
23 return 0;
24}1 2 3 4
Key takeaways
Stack memory is automatic and short-lived; heap memory lives until you
freeit.Allocate with
malloc(count * sizeof *p), always check forNULL, andfreeexactly once, then set the pointer toNULL.Leaks, use-after-free and double free are the classic bugs - AddressSanitizer (
-fsanitize=address) finds them for you.
Lesson quiz
5 questions · pass with 4 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: write real C
These run for real. Write the program, press Run tests, and read what the compiler tells you - learning to read compiler messages is half of learning C.
Exactly as much as you need
Read a count n, then n integers. Store them in an array allocated with malloc (exactly n elements), print their sum, and free the array.
For 4 then 5 10 15 20, print 50. If malloc fails, print Out of memory and return 1.
- Four numbers
- Negative numbers
Your code is compiled with gcc 14 (-Wall -Wextra) and run on Compiler Explorer (godbolt.org), a free public service.
Write your own strdup
Write char *duplicate(const char *s) that allocates exactly enough memory for a copy of s (remember the terminator!), copies it, and returns it. Return NULL if allocation fails. main reads a word, duplicates it, changes the copy's first letter to *, and prints both.
For hello print hello *ello.
- hello
- One letter
Your code is compiled with gcc 14 (-Wall -Wextra) and run on Compiler Explorer (godbolt.org), a free public service.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Sign in to ask questions, help other learners, and earn XP for taking part.
Loading posts…