pointers-memory · intermediate · ~25 min
Realloc + explicit zero-fill, with attention to OOM.
Resize a heap buffer with realloc, then zero only the newly added bytes. realloc leaves the extended region uninitialised — it may contain stale heap data — so zeroing just the new part is the safe building block.
Implement void *grow_zeroed(void *ptr, size_t old_size, size_t new_size) that calls realloc(ptr, new_size), zeroes the bytes from old_size up to new_size when growing, and returns the new pointer. No main — the grader calls it.
ptr — the existing block (may be NULL, in which case this acts like malloc). old_size — its current size in bytes. new_size — the desired size in bytes.
Returns the resized pointer, with bytes [old_size, new_size) set to 0 when growing. Returns NULL on allocation failure — in that case the original ptr is still valid and must NOT be freed.
char *p = malloc(4); memcpy(p, "abc", 4);
p = grow_zeroed(p, 4, 16) -> "abc\0" preserved, bytes 4..15 all zero
char *p = malloc(16); memset(p, 'X', 16);
p = grow_zeroed(p, 16, 8) -> shrunk; no zero-fill needed
ptr == NULL: behaves like malloc(new_size) then zeroes it.new_size <= old_size): no zero-fill.realloc into a temporary so an OOM doesn't lose (and leak) the original.realloc enlarges a buffer but leaves the new region uninitialised — that's a subtle source of information leaks (a CVE in OpenSSL leaked private-key bytes this way). Wrapping realloc with explicit zeroing of just the new region is the safer building block.
ptr (may be NULL), current old_size, desired new_size (bytes).
The resized pointer with the new region zeroed, or NULL on failure.
Use realloc (into a temporary) + memset. Zero only the new region. Don't free on OOM.
#include <stddef.h>
void *grow_zeroed(void *ptr, size_t old_size, size_t new_size) { /* TODO */ return NULL; }
Doing ptr = realloc(ptr, new_size) — if realloc returns NULL, the original is lost (leak). Use a temporary. Zeroing the whole buffer (defeats the purpose of realloc when shrinking).
new_size == 0 (call free or realloc-to-0, depending on impl); shrink (no zero-fill); grow (zero only the new region); ptr == NULL (acts like malloc).
Amortised O(new_size - old_size) for the zero-fill plus realloc cost.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.