X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/18c831dcd0ae4d660c70ccac69d27ed2a97851be..d04c0e00da3a27693bbf9cc4f2d5c88e56d80f20:/mem/alloc.c diff --git a/mem/alloc.c b/mem/alloc.c index e71ead4..8a62617 100644 --- a/mem/alloc.c +++ b/mem/alloc.c @@ -41,23 +41,37 @@ /*----- Functions and macros ----------------------------------------------*/ -/* --- @x_alloc@ --- * +/* --- @x_alloc@, @x_allocn@ --- * * * Arguments: @arena *a@ = pointer to underlying arena - * @size_t sz@ = size of block to allocate + * @size_t n@ = number of elements to allocate (for @x_allocv@) + * @size_t sz@ = size of elements to allocate * * Returns: Pointer to allocated block. * - * Use: Allocates memory. If there's not enough memory, the - * exception @EXC_NOMEM@ is thrown. + * Use: The @x_allocn@ function allocates memory for @n@ elements of + * @sz@ bytes each (or, perhaps, %%\emph{vice versa}). The + * @x_alloc@ function is the same, but with @n@ fixed equal + * to 1. If there's not enough memory, the exception + * @EXC_NOMEM@ is thrown. */ void *x_alloc(arena *a, size_t sz) { - void *p = A_ALLOC(a, sz); - if (!p) - THROW(EXC_NOMEM); - return (p); + void *p; + + p = A_ALLOC(a, sz); + if (!p) THROW(EXC_NOMEM); + else return (p); +} + +void *x_allocv(arena *a, size_t n, size_t sz) +{ + void *p; + + p = A_ALLOCV(a, n, sz); + if (!p) THROW(EXC_NOMEM); + else return (p); } /* --- @x_strdup@ --- * @@ -74,32 +88,48 @@ void *x_alloc(arena *a, size_t sz) char *x_strdup(arena *a, const char *s) { - size_t sz = strlen(s) + 1; - char *p = x_alloc(a, sz); - memcpy(p, s, sz); + char *p; size_t sz; + + sz = strlen(s) + 1; p = x_alloc(a, sz); memcpy(p, s, sz); return (p); } -/* --- @x_realloc@ --- * +/* --- @x_realloc@, @x_reallocv@ --- * * * Arguments: @arena *a@ = pointer to underlying arena * @void *p@ = pointer to a block of memory - * @size_t sz@ = new size desired for the block - * @size_t osz@ = size of the old block + * @size_t n@ = new number of elements (for @x_reallocv@) + * @size_t on@ = old number of elements (for @x_reallocv@) + * @size_t sz@ = size of elements (for @x_reallocv@) or new + * block size (for @x_realloc@) + * @size_t osz@ = size of the old block (for @x_realloc@) * * Returns: Pointer to the resized memory block (which is almost * certainly not in the same place any more). * * Use: Resizes a memory block. If there's not enough memory, the * exception @EXC_NOMEM@ is thrown. + * + * The @x_reallocv@ function adjusts a block which currently has + * space for @on@ elements each of size @sz@, so that it now has + * enough space for @n@ elements, preserving the initial @min(n, + * on)@ elements. The @x_realloc@ function is the same, but + * with @sz@ fixed equal to 1, and @n@ and @on@ renamed to @sz@ + * and @osz@ for historical reasons. */ void *x_realloc(arena *a, void *p, size_t sz, size_t osz) { p = A_REALLOC(a, p, sz, osz); - if (!p) - THROW(EXC_NOMEM); - return (p); + if (!p) THROW(EXC_NOMEM); + else return (p); +} + +void *x_reallocv(arena *a, void *p, size_t n, size_t on, size_t sz) +{ + p = A_REALLOCV(a, p, n, on, sz); + if (!p) THROW(EXC_NOMEM); + else return (p); } /* --- @x_free@ --- * @@ -116,17 +146,20 @@ void (x_free)(arena *a, void *p) { x_free(a, p); } /*----- Old functions for the standard arena ------------------------------*/ -/* --- @xmalloc@ --- * +/* --- @xmalloc@, @xmallocv@ --- * * - * Arguments: @size_t sz@ = size of block to allocate + * Arguments: @size_t n@ = number of elements to allocate (for @xmallocv@) + * @size_t sz@ = size of block to allocate * * Returns: Pointer to allocated block. * - * Use: Allocates memory. If there's not enough memory, the - * exception @EXC_NOMEM@ is thrown. + * Use: Allocates memory for @n@ elements each of size @sz@. For + * @xmalloc@, @n@ is fixed equal to 1. If there's not enough + * memory, the exception @EXC_NOMEM@ is thrown. */ void *(xmalloc)(size_t sz) { return xmalloc(sz); } +void *(xmallocv)(size_t n, size_t sz) { return xmallocv(n, sz); } /* --- @xstrdup@ --- * * @@ -141,21 +174,33 @@ void *(xmalloc)(size_t sz) { return xmalloc(sz); } char *(xstrdup)(const char *s) { return xstrdup(s); } -/* --- @xrealloc@ --- * +/* --- @xrealloc@, @xreallocv@ --- * * * Arguments: @void *p@ = pointer to a block of memory - * @size_t sz@ = new size desired for the block - * @size_t osz@ = size of the old block + * @size_t n@ = new number of elements (for @xreallocv@) + * @size_t on@ = old number of elements (for @xreallocv@) + * @size_t sz@ = size of elements (for @xreallocv@) or new + * block size (for @xrealloc@) + * @size_t osz@ = size of the old block (for @xrealloc@) * * Returns: Pointer to the resized memory block (which is almost * certainly not in the same place any more). * * Use: Resizes a memory block. If there's not enough memory, the * exception @EXC_NOMEM@ is thrown. + * + * The @xreallocv@ function adjusts a block which currently has + * space for @on@ elements each of size @sz@, so that it now has + * enough space for @n@ elements, preserving the initial @min(n, + * on)@ elements. The @xrealloc@ function is the same, but + * with @sz@ fixed equal to 1, and @n@ and @on@ renamed to @sz@ + * and @osz@ for historical reasons. */ void *(xrealloc)(void *p, size_t sz, size_t osz) -{ return xrealloc(p, sz, osz); } + { return xrealloc(p, sz, osz); } +void *(xreallocv)(void *p, size_t n, size_t on, size_t sz) + { return xreallocv(p, n, on, sz); } /* --- @xfree@ --- * *