diff options
author | Jon Santmyer <jon@jonsantmyer.com> | 2024-04-19 16:11:24 -0400 |
---|---|---|
committer | Jon Santmyer <jon@jonsantmyer.com> | 2024-04-19 16:11:24 -0400 |
commit | 5b1b3bec3f25ea5fc1f48c269f300c4211a1bac7 (patch) | |
tree | d47b7693dd91a8dd08a5c7def418fd132a7032ac /reallocarray.c | |
download | heap-5b1b3bec3f25ea5fc1f48c269f300c4211a1bac7.tar.gz heap-5b1b3bec3f25ea5fc1f48c269f300c4211a1bac7.tar.bz2 heap-5b1b3bec3f25ea5fc1f48c269f300c4211a1bac7.zip |
initial commit; mostly documented.
Diffstat (limited to 'reallocarray.c')
-rw-r--r-- | reallocarray.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/reallocarray.c b/reallocarray.c new file mode 100644 index 0000000..fc492f0 --- /dev/null +++ b/reallocarray.c @@ -0,0 +1,30 @@ +#include "malloc.h" +#include <assert.h> +#include <string.h> + +void* +__reallocarray_impl(heap_cache_t *cache, void *ptr, size_t nmemb, size_t w) +{ + /* Free if w == nmemb == 0*/ + if(w == 0 || nmemb == 0) { + __free_impl(cache, ptr); + return NULL; + } + + if(ptr == NULL) + return __calloc_impl(cache, nmemb, w); + + size_t allocw = w * nmemb; + w = REALW(w); + + bucket_obj_t *obj = OBJ_FROM_PTR(ptr); + assert(OBJ_VALID(obj)); + size_t oldw = OBJ_WIDTH(obj); + if(allocw < oldw) return ptr; + + ptr = __realloc_impl(cache, ptr, allocw); + size_t wdiff = allocw - oldw; + void *zeroat = (void*)(((uintptr_t)ptr) + oldw); + memset(zeroat, 0, wdiff); + return ptr; +} |