X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fxalloc.h;h=6122cc58b05d87da38d9f11f9dbcd849113c5b31;hb=7c59efd8bc7abb8c79ae969a65ece95e68c9be4c;hp=17ab5142187ed0dff35dc6c5e8dff445bfa76f63;hpb=8cdbf8e55b8aaad2b6f69893f4491b509eecc5df;p=gnulib.git diff --git a/lib/xalloc.h b/lib/xalloc.h index 17ab51421..6122cc58b 100644 --- a/lib/xalloc.h +++ b/lib/xalloc.h @@ -1,12 +1,13 @@ /* xalloc.h -- malloc with out-of-memory checking - Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2003, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2003, 2004, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, + Inc. - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #ifndef XALLOC_H_ # define XALLOC_H_ @@ -29,7 +29,7 @@ extern "C" { # ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) # define __attribute__(x) # endif # endif @@ -38,6 +38,14 @@ extern "C" { # define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) # endif +# ifndef ATTRIBUTE_MALLOC +# if __GNUC__ >= 3 +# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +# else +# define ATTRIBUTE_MALLOC +# endif +# endif + /* This function is always triggered when memory is exhausted. It must be defined by the application, either explicitly or by using gnulib's xalloc-die module. This is the @@ -45,13 +53,13 @@ extern "C" { memory allocation failure. */ extern void xalloc_die (void) ATTRIBUTE_NORETURN; -void *xmalloc (size_t s); -void *xzalloc (size_t s); -void *xcalloc (size_t n, size_t s); +void *xmalloc (size_t s) ATTRIBUTE_MALLOC; +void *xzalloc (size_t s) ATTRIBUTE_MALLOC; +void *xcalloc (size_t n, size_t s) ATTRIBUTE_MALLOC; void *xrealloc (void *p, size_t s); void *x2realloc (void *p, size_t *pn); -void *xmemdup (void const *p, size_t s); -char *xstrdup (char const *str); +void *xmemdup (void const *p, size_t s) ATTRIBUTE_MALLOC; +char *xstrdup (char const *str) ATTRIBUTE_MALLOC; /* Return 1 if an array of N objects, each of size S, cannot exist due to size arithmetic overflow. S must be positive and N must be @@ -98,10 +106,10 @@ char *xstrdup (char const *str); # if HAVE_INLINE # define static_inline static inline # else - void *xnmalloc (size_t n, size_t s); - void *xnrealloc (void *p, size_t n, size_t s); - void *x2nrealloc (void *p, size_t *pn, size_t s); - char *xcharalloc (size_t n); +void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC; +void *xnrealloc (void *p, size_t n, size_t s); +void *x2nrealloc (void *p, size_t *pn, size_t s); +char *xcharalloc (size_t n) ATTRIBUTE_MALLOC; # endif # ifdef static_inline @@ -109,6 +117,7 @@ char *xstrdup (char const *str); /* Allocate an array of N objects, each with S bytes of memory, dynamically, with error checking. S must be nonzero. */ +static_inline void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC; static_inline void * xnmalloc (size_t n, size_t s) { @@ -139,10 +148,10 @@ xnrealloc (void *p, size_t n, size_t s) allocating an initial block with a nonzero size, or by allocating a larger block. - In the following implementation, nonzero sizes are doubled so that - repeated reallocations have O(N log N) overall cost rather than - O(N**2) cost, but the specification for this function does not - guarantee that sizes are doubled. + In the following implementation, nonzero sizes are increased by a + factor of approximately 1.5 so that repeated reallocations have + O(N) overall cost rather than O(N**2) cost, but the + specification for this function does not guarantee that rate. Here is an example of use: @@ -153,9 +162,9 @@ xnrealloc (void *p, size_t n, size_t s) void append_int (int value) { - if (used == allocated) - p = x2nrealloc (p, &allocated, sizeof *p); - p[used++] = value; + if (used == allocated) + p = x2nrealloc (p, &allocated, sizeof *p); + p[used++] = value; } This causes x2nrealloc to allocate a block of some nonzero size the @@ -173,12 +182,12 @@ xnrealloc (void *p, size_t n, size_t s) void append_int (int value) { - if (used == allocated) - { - p = x2nrealloc (p, &allocated1, sizeof *p); - allocated = allocated1; - } - p[used++] = value; + if (used == allocated) + { + p = x2nrealloc (p, &allocated1, sizeof *p); + allocated = allocated1; + } + p[used++] = value; } */ @@ -191,22 +200,26 @@ x2nrealloc (void *p, size_t *pn, size_t s) if (! p) { if (! n) - { - /* The approximate size to use for initial small allocation - requests, when the invoking code specifies an old size of - zero. 64 bytes is the largest "small" request for the - GNU C library malloc. */ - enum { DEFAULT_MXFAST = 64 }; - - n = DEFAULT_MXFAST / s; - n += !n; - } + { + /* The approximate size to use for initial small allocation + requests, when the invoking code specifies an old size of + zero. 64 bytes is the largest "small" request for the + GNU C library malloc. */ + enum { DEFAULT_MXFAST = 64 }; + + n = DEFAULT_MXFAST / s; + n += !n; + } } else { - if (((size_t) -1) / 2 / s < n) - xalloc_die (); - n *= 2; + /* Set N = ceil (1.5 * N) so that progress is made if N == 1. + Check for overflow, so that N * S stays in size_t range. + The check is slightly conservative, but an exact check isn't + worth the trouble. */ + if ((size_t) -1 / 3 * 2 / s <= n) + xalloc_die (); + n += (n + 1) / 2; } *pn = n; @@ -216,6 +229,7 @@ x2nrealloc (void *p, size_t *pn, size_t s) /* Return a pointer to a new buffer of N bytes. This is like xmalloc, except it returns char *. */ +static_inline char *xcharalloc (size_t n) ATTRIBUTE_MALLOC; static_inline char * xcharalloc (size_t n) {