diff options
-rw-r--r-- | src/lib/klist.h | 10 | ||||
-rw-r--r-- | src/memory.c | 32 | ||||
-rw-r--r-- | src/memory.h | 11 |
3 files changed, 41 insertions, 12 deletions
diff --git a/src/lib/klist.h b/src/lib/klist.h index 1061d9869e..bb60449915 100644 --- a/src/lib/klist.h +++ b/src/lib/klist.h @@ -28,13 +28,15 @@ #include <stdlib.h> +#include "memory.h" + #define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \ typedef struct { \ size_t cnt, n, max; \ kmptype_t **buf; \ } kmp_##name##_t; \ static inline kmp_##name##_t *kmp_init_##name() { \ - return calloc(1, sizeof(kmp_##name##_t)); \ + return xcalloc(1, sizeof(kmp_##name##_t)); \ } \ static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \ size_t k; \ @@ -45,14 +47,14 @@ } \ static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \ ++mp->cnt; \ - if (mp->n == 0) return calloc(1, sizeof(kmptype_t)); \ + if (mp->n == 0) return xcalloc(1, sizeof(kmptype_t)); \ return mp->buf[--mp->n]; \ } \ static inline void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \ --mp->cnt; \ if (mp->n == mp->max) { \ mp->max = mp->max? mp->max<<1 : 16; \ - mp->buf = realloc(mp->buf, sizeof(void*) * mp->max); \ + mp->buf = xrealloc(mp->buf, sizeof(void*) * mp->max); \ } \ mp->buf[mp->n++] = p; \ } @@ -76,7 +78,7 @@ size_t size; \ } kl_##name##_t; \ static inline kl_##name##_t *kl_init_##name() { \ - kl_##name##_t *kl = calloc(1, sizeof(kl_##name##_t)); \ + kl_##name##_t *kl = xcalloc(1, sizeof(kl_##name##_t)); \ kl->mp = kmp_init(name); \ kl->head = kl->tail = kmp_alloc(name, kl->mp); \ kl->head->next = 0; \ diff --git a/src/memory.c b/src/memory.c index a878cb63da..8706724d72 100644 --- a/src/memory.c +++ b/src/memory.c @@ -1,5 +1,6 @@ // Various routines dealing with allocation and deallocation of memory. +#include <stdlib.h> #include <string.h> #include "vim.h" @@ -68,11 +69,7 @@ char_u *alloc(unsigned size) */ char_u *alloc_clear(unsigned size) { - char_u *p; - - p = lalloc((long_u)size, TRUE); - (void)memset(p, 0, (size_t)size); - return p; + return (char_u *)xcalloc(1, (size_t)size); } /* @@ -96,9 +93,7 @@ char_u *alloc_check(unsigned size) */ char_u *lalloc_clear(long_u size, int message) { - char_u *p = lalloc(size, message); - memset(p, 0, (size_t)size); - return p; + return (char_u *)xcalloc(1, (size_t)size); } /// Try to free memory. Used when trying to recover from out of memory errors. @@ -142,6 +137,27 @@ void *xmalloc(size_t size) return ret; } +void *xcalloc(size_t count, size_t size) +{ + void *ret = calloc(count, size); + + if (!ret && (!count || !size)) + ret = calloc(1, 1); + + if (!ret) { + try_to_free_memory(); + ret = calloc(count, size); + if (!ret && (!count || !size)) + ret = calloc(1, 1); + if (!ret) { + OUT_STR("Vim: Error: Out of memory.\n"); + preserve_exit(); + } + } + + return ret; +} + void *xrealloc(void *ptr, size_t size) { void *ret = realloc(ptr, size); diff --git a/src/memory.h b/src/memory.h index f5dbe6f453..324670115b 100644 --- a/src/memory.h +++ b/src/memory.h @@ -2,6 +2,8 @@ #define NEOVIM_MEMORY_H #include "func_attr.h" +#include "types.h" +#include "vim.h" char_u *alloc(unsigned size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); char_u *alloc_clear(unsigned size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); @@ -19,6 +21,15 @@ char_u *lalloc_clear(long_u size, int message) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_ void *xmalloc(size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1) FUNC_ATTR_NONNULL_RET; +/// calloc() wrapper +/// +/// @see {xmalloc} +/// @param count +/// @param size +/// @return pointer to allocated space. Never NULL +void *xcalloc(size_t count, size_t size) + FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE_PROD(1, 2) FUNC_ATTR_NONNULL_RET; + /// realloc() wrapper /// /// @see {xmalloc} |