Compare malloc, calloc and realloc. What does free do, and what are memory leaks and dangling pointers?
Show the explanation
All three allocate on the heap and return void * (or NULL on failure).
- `malloc(size)` gives
sizebytes. The contents are not initialised; they can hold anything. - `calloc(count, size)` gives room for
countobjects and sets every byte to zero. Good implementations also detect overflow incount * size. - `realloc(ptr, new_size)` resizes a block. It may grow it where it is, or allocate a new block, copy the old bytes and free the old one. So the address can change.
- Safe pattern:
int *tmp = realloc(p, n * sizeof *p); if (tmp) p = tmp;. Writingp = realloc(p, ...)loses the original block (a leak) when realloc fails and returns NULL. - `free(ptr)` hands the block back to the allocator. It does not clear the memory or set your pointer to NULL.
free(NULL)is a safe no-op.
Bugs to name in an interview
- Memory leak: losing the last pointer to a block without freeing it. Long-running programs grow until they fail.
- Dangling pointer / use-after-free: using a pointer after
free. This is undefined behaviour and a common security bug. Settingp = NULLright afterfree(p)helps. - Double free: calling
freetwice on the same block. Also undefined behaviour. - Forgetting to check for NULL after allocating.
Tools: Valgrind or AddressSanitizer (gcc -fsanitize=address -g) report leaks, use-after-free and out-of-bounds writes.
Style note: in C, do not cast the result of malloc (int *p = malloc(n * sizeof *p);). C converts void * automatically, and the cast can hide a missing #include <stdlib.h>. In C++ the cast is required, but there you would use new or containers anyway.
Original UniCircle question. Last reviewed 22 Oct 2026.
