diff options
author | Robert Ransom <rransom.8774@gmail.com> | 2012-02-12 20:09:56 -0800 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-02-17 11:42:19 -0500 |
commit | 806e0f7e19ed10f91b1a7477486991611c9732de (patch) | |
tree | 7a03f6fc7f24017c8dad885c36101206bbad2415 /src | |
parent | ff0059b924ec9bf1637eef81135b897da9210cc4 (diff) | |
download | tor-806e0f7e19ed10f91b1a7477486991611c9732de.tar.gz tor-806e0f7e19ed10f91b1a7477486991611c9732de.zip |
Add tor_calloc
Diffstat (limited to 'src')
-rw-r--r-- | src/common/util.c | 29 | ||||
-rw-r--r-- | src/common/util.h | 2 |
2 files changed, 31 insertions, 0 deletions
diff --git a/src/common/util.c b/src/common/util.c index 52fea2186a..9040877667 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -172,6 +172,35 @@ _tor_malloc_zero(size_t size DMALLOC_PARAMS) return result; } +/** Allocate a chunk of <b>nmemb</b>*<b>size</b> bytes of memory, fill + * the memory with zero bytes, and return a pointer to the result. + * Log and terminate the process on error. (Same as + * calloc(<b>nmemb</b>,<b>size</b>), but never returns NULL.) + * + * XXXX This implementation probably asserts in cases where it could + * work, because it only tries dividing SIZE_MAX by size (according to + * the calloc(3) man page, the size of an element of the nmemb-element + * array to be allocated), not by nmemb (which could in theory be + * smaller than size). Don't do that then. + */ +void * +_tor_calloc(size_t nmemb, size_t size DMALLOC_PARAMS) +{ + /* You may ask yourself, "wouldn't it be smart to use calloc instead of + * malloc+memset? Perhaps libc's calloc knows some nifty optimization trick + * we don't!" Indeed it does, but its optimizations are only a big win when + * we're allocating something very big (it knows if it just got the memory + * from the OS in a pre-zeroed state). We don't want to use tor_malloc_zero + * for big stuff, so we don't bother with calloc. */ + void *result; + size_t max_nmemb = (size == 0) ? SIZE_MAX : SIZE_MAX/size; + + tor_assert(nmemb < max_nmemb); + + result = _tor_malloc_zero((nmemb * size) DMALLOC_FN_ARGS); + return result; +} + /** Change the size of the memory block pointed to by <b>ptr</b> to <b>size</b> * bytes long; return the new memory block. On error, log and * terminate. (Like realloc(ptr,size), but never returns NULL.) diff --git a/src/common/util.h b/src/common/util.h index 1bad24bf72..955a682831 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -73,6 +73,7 @@ void *_tor_malloc(size_t size DMALLOC_PARAMS) ATTR_MALLOC; void *_tor_malloc_zero(size_t size DMALLOC_PARAMS) ATTR_MALLOC; void *_tor_malloc_roundup(size_t *size DMALLOC_PARAMS) ATTR_MALLOC; +void *_tor_calloc(size_t nmemb, size_t size DMALLOC_PARAMS) ATTR_MALLOC; void *_tor_realloc(void *ptr, size_t size DMALLOC_PARAMS); char *_tor_strdup(const char *s DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1)); char *_tor_strndup(const char *s, size_t n DMALLOC_PARAMS) @@ -107,6 +108,7 @@ extern int dmalloc_free(const char *file, const int line, void *pnt, #define tor_malloc(size) _tor_malloc(size DMALLOC_ARGS) #define tor_malloc_zero(size) _tor_malloc_zero(size DMALLOC_ARGS) +#define tor_calloc(nmemb,size) _tor_calloc(nmemb, size DMALLOC_ARGS) #define tor_malloc_roundup(szp) _tor_malloc_roundup(szp DMALLOC_ARGS) #define tor_realloc(ptr, size) _tor_realloc(ptr, size DMALLOC_ARGS) #define tor_strdup(s) _tor_strdup(s DMALLOC_ARGS) |