Growing with realloc
Resize a dynamic array.
Growing with realloc is a free C Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
When One malloc Isn't Enough
Sometimes you allocate an array, fill it, and then discover you need more room. You can't just write past the end.
realloc lets you resize an existing heap block, keeping the data that was already there.
The realloc Signature
realloc(ptr, new_bytes) takes the old pointer and the new total size in bytes.
It returns a pointer to a block of the new size. The first part of the data is preserved up to the smaller of the old and new sizes.
int *bigger = realloc(a, new_n * sizeof(*a));It May Move the Block
realloc may grow the block in place, or it may allocate a new block, copy your data, and free the old one.
Either way, the old pointer might become invalid. You must use the returned pointer from now on.
a = realloc(a, new_n * sizeof(*a));
/* the old value of a may no longer be valid */The Self-Assign Trap
Writing a = realloc(a, ...) looks tidy but is dangerous: if realloc returns NULL, you have overwritten a and lost the original pointer, leaking the old block.
Use a temporary variable instead.
int *tmp = realloc(a, new_n * sizeof(*a));
if (tmp == NULL) { /* a is still valid */ return 1; }
a = tmp;Growing an Array Safely
This program allocates 3 ints, then grows to 6 with realloc, preserving the first three values.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = malloc(3 * sizeof(*a));
if (!a) return 1;
for (int i = 0; i < 3; i++) a[i] = i + 1;
int *tmp = realloc(a, 6 * sizeof(*a));
if (!tmp) { free(a); return 1; }
a = tmp;
for (int i = 3; i < 6; i++) a[i] = i + 1;
for (int i = 0; i < 6; i++) printf("%d\n", a[i]);
free(a);
return 0;
}New Bytes Are Uninitialized
When you grow a block, the extra space at the end holds garbage, just like fresh malloc memory.
realloc preserves your old data but does not zero the new region. Initialize it before reading.
a = realloc(a, 6 * sizeof(*a));
for (int i = 3; i < 6; i++) a[i] = 0; /* clear new slots */The Doubling Strategy
Calling realloc for every single element is slow. A classic trick is to double the capacity whenever you run out of space.
This keeps the number of reallocations small as the array grows, giving good average performance.
if (count == cap) {
cap = cap ? cap * 2 : 4;
int *tmp = realloc(a, cap * sizeof(*a));
if (!tmp) { free(a); return 1; }
a = tmp;
}Building an Array by Appending
This program starts empty and appends numbers, doubling capacity as needed.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = NULL;
size_t count = 0, cap = 0;
for (int v = 1; v <= 5; v++) {
if (count == cap) {
cap = cap ? cap * 2 : 2;
int *tmp = realloc(a, cap * sizeof(*a));
if (!tmp) { free(a); return 1; }
a = tmp;
}
a[count++] = v;
}
for (size_t i = 0; i < count; i++) printf("%d\n", a[i]);
free(a);
return 0;
}realloc(NULL, n) Acts Like malloc
If you pass NULL as the pointer, realloc behaves exactly like malloc.
That's why starting with a = NULL works in the doubling loop: the very first realloc allocates the initial block.
int *a = NULL;
a = realloc(a, 4 * sizeof(*a)); /* same as malloc(4 * sizeof(*a)) */Shrinking a Block
realloc can also make a block smaller. The data up to the new size is kept; the rest is discarded.
Shrinking can free memory back, though implementations are free to keep the larger block.
int *tmp = realloc(a, 2 * sizeof(*a)); /* down from more */
if (tmp) a = tmp;Avoid Overflow in the Math
When capacity grows large, cap * sizeof(*a) could overflow a size_t and wrap to a tiny number.
For huge arrays, guard the multiplication, or use reallocarray on systems that provide it.
if (cap > SIZE_MAX / sizeof(*a)) { /* overflow */ return 1; }
int *tmp = realloc(a, cap * sizeof(*a));Quick Check
Test your understanding of realloc.
Recap
realloc resizes a heap block and may move it, so always use the returned pointer.
Assign to a temporary so a failure doesn't leak the original. Grow by doubling for speed, initialize new slots, and remember realloc(NULL, n) equals malloc. Next you'll wrap this logic in a reusable vector type.
Frequently asked questions
Is the “Growing with realloc” lesson free?
Yes — the full text of “Growing with realloc” is free to read here on the web, and the C Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C Academy course, upgrade to CoddyKit PRO.
What will I learn in “Growing with realloc”?
Resize a dynamic array. You practise C Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C Academy?
No prior experience is required. C Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Growing with realloc” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C Academy lesson?
Yes. Every C Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Allocating an Array
- Growing with realloc
- A Reusable Vector Type
- Freeing and Avoiding Leaks