NULL Has Two Meanings
my_realloc(p, 0) → intentional free, NULL.
my_realloc(p, positive_size) → NULL on failure; p survives.
This is our custom API. Do not use its zero-size rule as a portable standard-C realloc rule.
1 / 7
my_realloc(p, 0) → intentional free, NULL.
my_realloc(p, positive_size) → NULL on failure; p survives.
This is our custom API. Do not use its zero-size rule as a portable standard-C realloc rule.
Live 12-byte block; request 20 bytes; allocation fails.
Who owns the old bytes?
The caller still does. No free and no metadata change occurred.
Allocate 20 → copy 12 → free old → return new.
Copying 20 overreads the source. Freeing first allows the allocator to reuse the source too soon.
Capacity 12; request 5; return the same pointer.
The exercise keeps recorded capacity 12. The first five bytes remain. Splitting requires enough room for another aligned header and useful payload.
An unchecked header + SIZE_MAX can wrap to a tiny allocation.
Check metadata addition, alignment padding, and the signed sbrk range before changing the heap.
Check size > SIZE_MAX/count before multiplication, with zero arguments handled separately.
Then allocate and clear count*size bytes. Recycling a free block does not clear its previous contents.
my_realloc(NULL, 0) returns NULL and allocates nothing.
A NULL result after freeing a live pointer is not a growth failure. The requested size tells the caller which ownership rule applies.