c language · high
C: malloc / free & Heap Bugs
Correct C heap use starts with allocation: malloc returns a void* to uninitialized memory (calloc zeroes and checks count*size overflow) and returns NULL on failure, so always check; size allocations as count * sizeof *p to keep the size tied to the pointer's type, and do not cast malloc's result in C. Every malloc needs exactly one matching free, and since the allocator records the block size, free takes only the pointer. After free(p) the pointer dangles: reading or writing through it is use-after-free and freeing it again is a double free — both undefined behavior and frequent security exploits — so set p = NULL afterward, which turns accidental reuse into a clean NULL-deref and is safe because free(NULL) is a no-op. The opposite failure, a memory leak, is losing the last pointer to an unfreed block. realloc may move the block, returning a new pointer and freeing the old, and returns NULL on failure while leaving the original allocated, so never write p = realloc(p, ...) — capture into a temporary and assign back only on success, or you leak. Above the individual bugs, the real discipline is ownership: document who frees each allocation, release in reverse order of acquisition, and verify with Valgrind or AddressSanitizer, which detect leaks, double-free, and use-after-free at runtime.
C heap discipline: check malloc for NULL (size = count*sizeof *p), free each block exactly once; after free the pointer dangles (use-after-free/double-free are UB — set it NULL); realloc may move/fail so assign its result via a temp; document ownership and verify with Valgrind/ASan.
The code
int* p = malloc(n * sizeof *p); // size = count * element sizeif (!p) { /* handle out-of-memory */}// ... use p ...free(p);p = NULL; // avoid a dangling pointer / accidental reuse
// realloc can MOVE the block; never lose the old pointer:int* q = realloc(p, m * sizeof *q);if (q) p = q; // only overwrite p if realloc succeededWhat this lesson walks through
- 01Allocate correctly, check, and free once
- 02Dangling, double free, use-after-free
- 03Gotcha — realloc moves, double free, UAF
- 04realloc safely; ownership discipline
malloc returns a void* to uninitialized memory (use calloc for zeroed) and returns NULL on failure — always check. Size it as count * sizeof *p (using the dereferenced pointer keeps the type in sync). Every malloc needs exactly one matching free; the allocator tracks the block size, so free(p) needs only the pointer. In C you do not cast malloc's result.
See it animated — step by step, at your own pace
Unlock the full interactive walkthrough of C: malloc / free & Heap Bugs and 100+ animated C++ interview lessons.