diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/resource.c | 37 | ||||
-rw-r--r-- | lib/resource.h | 8 | ||||
-rw-r--r-- | lib/xmalloc.c | 20 |
3 files changed, 63 insertions, 2 deletions
diff --git a/lib/resource.c b/lib/resource.c index 9e626815..289af933 100644 --- a/lib/resource.c +++ b/lib/resource.c @@ -328,6 +328,42 @@ mb_allocz(pool *p, unsigned size) } /** + * mb_realloc - reallocate a memory block + * @p: pool + * @m: memory block + * @size: new size of the block + * + * mb_realloc() changes the size of the memory block @m to a given size. + * The contents will be unchanged to the minimum of the old and new sizes; + * newly allocated memory will be uninitialized. If @m is NULL, the call + * is equivalent to mb_alloc(@p, @size). + * + * Like mb_alloc(), mb_realloc() also returns a pointer to the memory + * chunk , not to the resource, hence you have to free it using + * mb_free(), not rfree(). + */ +void * +mb_realloc(pool *p, void *m, unsigned size) +{ + struct mblock *ob = NULL; + + if (m) + { + ob = SKIP_BACK(struct mblock, data, m); + if (ob->r.n.next) + rem_node(&ob->r.n); + } + + struct mblock *b = xrealloc(ob, sizeof(struct mblock) + size); + + b->r.class = &mb_class; + add_tail(&p->inside, &b->r.n); + b->size = size; + return b->data; +} + + +/** * mb_free - free a memory block * @m: memory block * @@ -339,3 +375,4 @@ mb_free(void *m) struct mblock *b = SKIP_BACK(struct mblock, data, m); rfree(b); } + diff --git a/lib/resource.h b/lib/resource.h index 42ed26ed..8dd441f0 100644 --- a/lib/resource.h +++ b/lib/resource.h @@ -47,6 +47,7 @@ extern pool root_pool; void *mb_alloc(pool *, unsigned size); void *mb_allocz(pool *, unsigned size); +void *mb_realloc(pool *p, void *m, unsigned size); void mb_free(void *); /* Memory pools with linear allocation */ @@ -75,12 +76,13 @@ void sl_free(slab *, void *); #ifdef HAVE_LIBDMALLOC /* * The standard dmalloc macros tend to produce lots of namespace - * conflicts and we use only xmalloc and xfree, so we can define - * the stubs ourselves. + * conflicts and we use only xmalloc, xrealloc and xfree, so we + * can define the stubs ourselves. */ #define DMALLOC_DISABLE #include <dmalloc.h> #define xmalloc(size) _xmalloc_leap(__FILE__, __LINE__, size) +#define xrealloc(size) _xrealloc_leap(__FILE__, __LINE__, size) #define xfree(ptr) _xfree_leap(__FILE__, __LINE__, ptr) #else /* @@ -89,7 +91,9 @@ void sl_free(slab *, void *); * the renaming. */ #define xmalloc bird_xmalloc +#define xrealloc bird_xrealloc void *xmalloc(unsigned); +void *xrealloc(void *, unsigned); #define xfree(x) free(x) #endif diff --git a/lib/xmalloc.c b/lib/xmalloc.c index bc386c83..da2f0941 100644 --- a/lib/xmalloc.c +++ b/lib/xmalloc.c @@ -32,4 +32,24 @@ xmalloc(unsigned size) die("Unable to allocate %d bytes of memory", size); } +/** + * xrealloc - realloc with checking + * @ptr: original memory block + * @size: block size + * + * This function is equivalent to realloc() except that in case of + * failure it calls die() to quit the program instead of returning + * a %NULL pointer. + * + * Wherever possible, please use the memory resources instead. + */ +void * +xrealloc(void *ptr, unsigned size) +{ + void *p = realloc(ptr, size); + if (p) + return p; + die("Unable to allocate %d bytes of memory", size); +} + #endif |