scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 2a2e57ae043b6d78a5dbd50761971d6508540729
parent 2b33af36beceaf67507ab881f113d68a371a4f13
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Tue, 17 Jun 2025 20:16:23 +0200

libc/malloc: Unify malloc and realloc

realloc(p, 0) should behave like malloc(0), but we were not setting the
same errno values, and we were returning NULL in both cases, that makes
more difficult to differentiate the case when 0 is passed and the case
when we don't have enough memory. Given that the traditional behaviour
was always to return a pointer that could be freed (and even that was
the original behaviour in scc) this commit restores that behaviour.

Diffstat:
Msrc/libc/stdlib/malloc.c | 5++++-
Msrc/libc/stdlib/realloc.c | 4++--
2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/libc/stdlib/malloc.c b/src/libc/stdlib/malloc.c @@ -1,3 +1,4 @@ +#include <errno.h> #include <stdint.h> #include <stdlib.h> #include <string.h> @@ -136,8 +137,10 @@ malloc(size_t nbytes) Header *cur, *prev; size_t nunits; - if (nbytes == 0 || nbytes > SIZE_MAX - sizeof(Header)-1) + if (nbytes > SIZE_MAX - sizeof(Header)-1) { + errno = ENOMEM; return NULL; + } /* 1 unit for header plus enough units to fit nbytes */ nunits = (nbytes+sizeof(Header)-1)/sizeof(Header) + 1; diff --git a/src/libc/stdlib/realloc.c b/src/libc/stdlib/realloc.c @@ -13,8 +13,8 @@ realloc(void *ptr, size_t nbytes) size_t nunits, avail, onbytes, n; if (nbytes == 0) { - errno = EINVAL; - return NULL; + free(ptr); + ptr = NULL; } if (nbytes > SIZE_MAX - sizeof(Header)-1) {