diff options
Diffstat (limited to 'lib/util/mallocvar.h')
-rw-r--r-- | lib/util/mallocvar.h | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/lib/util/mallocvar.h b/lib/util/mallocvar.h index 00ba6484..23b28c40 100644 --- a/lib/util/mallocvar.h +++ b/lib/util/mallocvar.h @@ -24,30 +24,40 @@ extern "C" { static __inline__ void mallocProduct(void ** const resultP, - unsigned int const factor1, + size_t const factor1, unsigned int const factor2) { /*---------------------------------------------------------------------------- malloc a space whose size in bytes is the product of 'factor1' and - 'factor2'. But if that size cannot be represented as an unsigned int, - return NULL without allocating anything. Also return NULL if the malloc - fails. + 'factor2'. But if the malloc fails, or that size is too large even to + request from malloc, return NULL without allocating anything. If either factor is zero, malloc a single byte. - - Note that malloc() actually takes a size_t size argument, so the - proper test would be whether the size can be represented by size_t, - not unsigned int. But there is no reliable indication available to - us, like UINT_MAX, of what the limitations of size_t are. We - assume size_t is at least as expressive as unsigned int and that - nobody really needs to allocate more than 4GB of memory. -----------------------------------------------------------------------------*/ + /* C99 introduces SIZE_MAX, the maximum size_t value. + + Pre-C99, we do the best we can, assuming conventional encoding of + numbers and that size_t is unsigned. + */ + size_t const sizeMax = +#if defined(SIZE_MAX) + SIZE_MAX +#else + ~((size_t)0) +#endif + ; + if (factor1 == 0 || factor2 == 0) *resultP = malloc(1); else { - if (UINT_MAX / factor2 < factor1) + /* N.B. The type of malloc's argument is size_t */ + if ((size_t)factor2 != factor2) *resultP = NULL; - else - *resultP = malloc(factor1 * factor2); + else { + if (sizeMax / factor2 < factor1) + *resultP = NULL; + else + *resultP = malloc(factor1 * factor2); + } } } @@ -55,18 +65,30 @@ mallocProduct(void ** const resultP, static __inline__ void reallocProduct(void ** const blockP, - unsigned int const factor1, + size_t const factor1, unsigned int const factor2) { + size_t const sizeMax = +#if defined(SIZE_MAX) + SIZE_MAX +#else + ~((size_t)0) +#endif + ; + void * const oldBlockP = *blockP; void * newBlockP; - if (UINT_MAX / factor2 < factor1) + /* N.B. The type of realloc's argument is size_t */ + if ((size_t)factor2 != factor2) newBlockP = NULL; - else - newBlockP = realloc(oldBlockP, factor1 * factor2); - + else { + if (sizeMax / factor2 < factor1) + newBlockP = NULL; + else + newBlockP = realloc(oldBlockP, factor1 * factor2); + } if (newBlockP) *blockP = newBlockP; else { |