From 878370c29af1c61ba43ff32fbed661e883d742e2 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Thu, 27 Feb 2014 13:55:19 +0900 Subject: [PATCH] gurantee allocators return NULL given size is zero --- include/picrin.h | 3 ++- src/gc.c | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/include/picrin.h b/include/picrin.h index 9edf3826..eb42720c 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -130,7 +130,8 @@ enum pic_parser_res { /* if parser is successfully done, return the number of exprs (>= 0) */ }; -void *pic_alloc(pic_state *, size_t); +void *pic_malloc(pic_state *, size_t); +#define pic_alloc(pic,size) pic_malloc(pic,size) /* obsoleted */ void *pic_realloc(pic_state *, void *, size_t); void *pic_calloc(pic_state *, size_t, size_t); struct pic_object *pic_obj_alloc(pic_state *, size_t, enum pic_tt); diff --git a/src/gc.c b/src/gc.c index f5c5e777..26d81341 100644 --- a/src/gc.c +++ b/src/gc.c @@ -42,6 +42,7 @@ struct pic_heap { struct heap_page *pages; }; + static void heap_init(struct pic_heap *heap) { @@ -113,12 +114,28 @@ add_heap_page(pic_state *pic) pic->heap->pages = page; } +static void * +alloc(void *ptr, size_t size) +{ + if (size == 0) { + if (ptr) { + free(ptr); + } + return NULL; + } + if (ptr) { + return realloc(ptr, size); + } else { + return malloc(size); + } +} + void * -pic_alloc(pic_state *pic, size_t size) +pic_malloc(pic_state *pic, size_t size) { void *ptr; - ptr = malloc(size); + ptr = alloc(NULL, size); if (ptr == NULL && size > 0) { pic_abort(pic, "memory exhausted"); } @@ -128,7 +145,7 @@ pic_alloc(pic_state *pic, size_t size) void * pic_realloc(pic_state *pic, void *ptr, size_t size) { - ptr = realloc(ptr, size); + ptr = alloc(ptr, size); if (ptr == NULL && size > 0) { pic_abort(pic, "memory exhausted"); } @@ -140,10 +157,12 @@ pic_calloc(pic_state *pic, size_t count, size_t size) { void *ptr; - ptr = calloc(count ,size); + size *= count; + ptr = alloc(NULL, size); if (ptr == NULL && size > 0) { pic_abort(pic, "memory exhausted"); } + memset(ptr, 0, size); return ptr; }