diff options
Diffstat (limited to 'libmisc')
-rw-r--r-- | libmisc/include/libmisc/alloc.h | 26 | ||||
-rw-r--r-- | libmisc/map.c | 3 |
2 files changed, 28 insertions, 1 deletions
diff --git a/libmisc/include/libmisc/alloc.h b/libmisc/include/libmisc/alloc.h new file mode 100644 index 0000000..afddbce --- /dev/null +++ b/libmisc/include/libmisc/alloc.h @@ -0,0 +1,26 @@ +/* libmisc/alloc.h - Type-safe wrappers around alloca and malloc + * + * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIBMISC_ALLOC_H_ +#define _LIBMISC_ALLOC_H_ + +#include <alloca.h> /* for alloca() */ +#include <stdlib.h> /* for calloc(), free() */ +#include <string.h> /* for memset() */ + +#define stack_alloc(N, TYP) ({ \ + size_t _size; \ + TYP *_ret = NULL; \ + if (!__builtin_mul_overflow(N, sizeof(TYP), &_size)) { \ + _ret = alloca(_size); \ + memset(_ret, 0, _size); \ + } \ + _ret; \ +}) + +#define heap_alloc(N, TYP) ((TYP *)calloc(N, sizeof(TYP))) + +#endif /* _LIBMISC_ALLOC_H_ */ diff --git a/libmisc/map.c b/libmisc/map.c index 7629c8c..cc34c16 100644 --- a/libmisc/map.c +++ b/libmisc/map.c @@ -8,6 +8,7 @@ #include <string.h> #include <libmisc/hash.h> +#include <libmisc/alloc.h> #include <libmisc/assert.h> #include <libmisc/map.h> @@ -63,7 +64,7 @@ static inline void _map_lookup(struct _map *m, void *keyp, static inline void _map_resize(struct _map *m, size_t new_nbuckets) { assert(m); assert(new_nbuckets); - struct _map_kv_list *new_buckets = calloc(new_nbuckets, sizeof(struct _map_kv_list)); + struct _map_kv_list *new_buckets = heap_alloc(new_nbuckets, struct _map_kv_list); for (size_t i = 0; i < m->nbuckets; i++) { while (m->buckets[i].front) { struct _map_kv_list_node *kv = m->buckets[i].front; |