calloc and realloc
beginner13 min readLesson 47 of 148
Zero-filled allocation, and growing an array while keeping its contents.
calloc: malloc + zero fill
int *p = calloc(n, sizeof(int)); // n elements, EACH set to 0
Two differences from malloc(n * sizeof(int)): two arguments (count, size),
and every byte is zeroed. Choose calloc when "all zeros" is the state you
want; choose malloc when you will overwrite everything immediately.
realloc: grow or shrink
int *q = realloc(p, new_count * sizeof(int));
realloc may extend in place or move the block โ if it moves, it COPIES the
old contents. Either way you get the block's new address.
The realloc idiom โ do not lose your only pointer
int *tmp = realloc(p, m * sizeof(int));
if (tmp == NULL) {
free(p); // old block is still valid; clean up
return 1;
}
p = tmp; // success: adopt the new address
Assigning straight to p (p = realloc(p, ...)) is the classic bug: on
failure it returns NULL and the ORIGINAL address is lost โ a leak with no way
to free.
Growing a dynamic array
int count = 0, cap = 4;
int *a = malloc(cap * sizeof(int));
// ... need more room ...
cap *= 2;
int *tmp = realloc(a, cap * sizeof(int));
if (tmp == NULL) { free(a); /* handle */ }
else a = tmp;
This grow-by-doubling pattern is the heart of every dynamic array you will build in module 20.