Skip to main content

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.

Now practice

Allocation Workbenchmalloc/calloc/realloc mechanics: fill, grow, and preserve.4 challenges ยท ยท ~18 min