On Sun, Nov 03, 2013 at 09:13:33PM +0100, Ondřej Bílka wrote: > On Sun, Nov 03, 2013 at 12:04:36PM -0800, Paul Eggert wrote: > > Ondřej Bílka wrote: > > > +XALLOC_INLINE void * > > > +nmalloc (size_t n, size_t s) > > > +{ > > > + if (xalloc_oversized (n, s)) > > > + xalloc_die (); > > > + return xmalloc (n * s); > > > +} > > > > This is the same as the existing xnmalloc, so why bother with a new name? > > Similarly for the other changes. > > I accidentally inlined wrong version. As idea is to handle overflow by > oom logic these should be: > > nmalloc (size_t n, size_t s) > { > if (xalloc_oversized (n, s)) > NULL; > return malloc (n * s); > } >
A new version is here. Macros are added for consistency of api but not neccessary. * lib/xalloc.h (NMALLOC, NREALLOC, nmalloc, nrealloc): Add. * lib/xmalloca.h (XNMALLOCA): Likewise. diff --git a/lib/xalloc.h b/lib/xalloc.h index 6c9b53b..66799be 100644 --- a/lib/xalloc.h +++ b/lib/xalloc.h @@ -93,6 +93,15 @@ char *xstrdup (char const *str) #define XCALLOC(n, t) \ ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))) +/* Allocate memory for N elements of type T, with overflow checking. */ +/* extern t *NMALLOC (size_t n, typename t); */ +#define NMALLOC(n, t) \ + ((t *) (sizeof (t) == 1 ? malloc (n) : nmalloc (n, sizeof (t)))) + +/* Rellocate memory for N elements of type T, with overflow checking. */ +/* extern t *NREALLOC (void *p, size_t n, typename t); */ +#define NREALLOC(p, n, t) ((t *) (nrealloc (p, n, sizeof (t)))) + /* Allocate an array of N objects, each with S bytes of memory, dynamically, with error checking. S must be nonzero. */ @@ -107,6 +116,17 @@ xnmalloc (size_t n, size_t s) return xmalloc (n * s); } +/* Allocate an array of N objects, each with S bytes of memory, + dynamically, with overflow checking. S must be nonzero. */ + +XALLOC_INLINE void *nmalloc (size_t n, size_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)); +XALLOC_INLINE void * +nmalloc (size_t n, size_t s) +{ + return malloc (xalloc_oversized (n, s) ? SIZE_MAX : n * s); +} + /* Change the size of an allocated block of memory P to an array of N objects each of S bytes, with error checking. S must be nonzero. */ @@ -120,6 +140,17 @@ xnrealloc (void *p, size_t n, size_t s) return xrealloc (p, n * s); } +/* Change the size of an allocated block of memory P to an array of N + objects each of S bytes, with overflow checking. S must be nonzero. */ + +XALLOC_INLINE void *nrealloc (void *p, size_t n, size_t s) + _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); +XALLOC_INLINE void * +nrealloc (void *p, size_t n, size_t s) +{ + return realloc (p, xalloc_oversized (n, s) ? SIZE_MAX : n * s); +} + /* If P is null, allocate a block of at least *PN such objects; otherwise, reallocate P so that it contains more than *PN objects each of S bytes. *PN must be nonzero unless P is null, and S must diff --git a/lib/xmalloca.h b/lib/xmalloca.h index 2f7567d..4ab1a03 100644 --- a/lib/xmalloca.h +++ b/lib/xmalloca.h @@ -55,6 +55,7 @@ extern void * xmmalloca (size_t n); xnmalloc ((n), (s)) #endif +#define XNMALLOCA(n, t) ((t *) xnmalloca (x, sizeof (t))) #ifdef __cplusplus }