1 /* xalloc.h -- malloc with out-of-memory checking
3 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 2000, 2003, 2004, 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
31 # ifndef __attribute__
32 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
33 # define __attribute__(x)
37 # ifndef ATTRIBUTE_NORETURN
38 # define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
41 # ifndef ATTRIBUTE_MALLOC
43 # define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
45 # define ATTRIBUTE_MALLOC
49 # ifndef ATTRIBUTE_ALLOC_SIZE
50 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
51 # define ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
53 # define ATTRIBUTE_ALLOC_SIZE(args)
57 /* This function is always triggered when memory is exhausted.
58 It must be defined by the application, either explicitly
59 or by using gnulib's xalloc-die module. This is the
60 function to call when one wants the program to die because of a
61 memory allocation failure. */
62 extern void xalloc_die (void) ATTRIBUTE_NORETURN;
64 void *xmalloc (size_t s)
65 ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1));
66 void *xzalloc (size_t s)
67 ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1));
68 void *xcalloc (size_t n, size_t s)
69 ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1, 2));
70 void *xrealloc (void *p, size_t s)
71 ATTRIBUTE_ALLOC_SIZE ((2));
72 void *x2realloc (void *p, size_t *pn);
73 void *xmemdup (void const *p, size_t s)
74 ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((2));
75 char *xstrdup (char const *str)
78 /* Return 1 if an array of N objects, each of size S, cannot exist due
79 to size arithmetic overflow. S must be positive and N must be
80 nonnegative. This is a macro, not an inline function, so that it
81 works correctly even when SIZE_MAX < N.
83 By gnulib convention, SIZE_MAX represents overflow in size
84 calculations, so the conservative dividend to use here is
85 SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
86 However, malloc (SIZE_MAX) fails on all known hosts where
87 sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
88 exactly-SIZE_MAX allocations on such hosts; this avoids a test and
89 branch when S is known to be 1. */
90 # define xalloc_oversized(n, s) \
91 ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
94 /* In the following macros, T must be an elementary or structure/union or
95 typedef'ed type, or a pointer to such a type. To apply one of the
96 following macros to a function pointer or array type, you need to typedef
97 it first and use the typedef name. */
99 /* Allocate an object of type T dynamically, with error checking. */
100 /* extern t *XMALLOC (typename t); */
101 # define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
103 /* Allocate memory for N elements of type T, with error checking. */
104 /* extern t *XNMALLOC (size_t n, typename t); */
105 # define XNMALLOC(n, t) \
106 ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
108 /* Allocate an object of type T dynamically, with error checking,
110 /* extern t *XZALLOC (typename t); */
111 # define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
113 /* Allocate memory for N elements of type T, with error checking,
115 /* extern t *XCALLOC (size_t n, typename t); */
116 # define XCALLOC(n, t) \
117 ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
121 # define static_inline static inline
123 void *xnmalloc (size_t n, size_t s)
124 ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1, 2));
125 void *xnrealloc (void *p, size_t n, size_t s)
126 ATTRIBUTE_ALLOC_SIZE ((2, 3));
127 void *x2nrealloc (void *p, size_t *pn, size_t s);
128 char *xcharalloc (size_t n)
129 ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1));
132 # ifdef static_inline
134 /* Allocate an array of N objects, each with S bytes of memory,
135 dynamically, with error checking. S must be nonzero. */
137 static_inline void *xnmalloc (size_t n, size_t s)
138 ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1, 2));
140 xnmalloc (size_t n, size_t s)
142 if (xalloc_oversized (n, s))
144 return xmalloc (n * s);
147 /* Change the size of an allocated block of memory P to an array of N
148 objects each of S bytes, with error checking. S must be nonzero. */
150 static_inline void *xnrealloc (void *p, size_t n, size_t s)
151 ATTRIBUTE_ALLOC_SIZE ((2, 3));
153 xnrealloc (void *p, size_t n, size_t s)
155 if (xalloc_oversized (n, s))
157 return xrealloc (p, n * s);
160 /* If P is null, allocate a block of at least *PN such objects;
161 otherwise, reallocate P so that it contains more than *PN objects
162 each of S bytes. *PN must be nonzero unless P is null, and S must
163 be nonzero. Set *PN to the new number of objects, and return the
164 pointer to the new block. *PN is never set to zero, and the
165 returned pointer is never null.
167 Repeated reallocations are guaranteed to make progress, either by
168 allocating an initial block with a nonzero size, or by allocating a
171 In the following implementation, nonzero sizes are increased by a
172 factor of approximately 1.5 so that repeated reallocations have
173 O(N) overall cost rather than O(N**2) cost, but the
174 specification for this function does not guarantee that rate.
176 Here is an example of use:
180 size_t allocated = 0;
183 append_int (int value)
185 if (used == allocated)
186 p = x2nrealloc (p, &allocated, sizeof *p);
190 This causes x2nrealloc to allocate a block of some nonzero size the
191 first time it is called.
193 To have finer-grained control over the initial size, set *PN to a
194 nonzero value before calling this function with P == NULL. For
199 size_t allocated = 0;
200 size_t allocated1 = 1000;
203 append_int (int value)
205 if (used == allocated)
207 p = x2nrealloc (p, &allocated1, sizeof *p);
208 allocated = allocated1;
216 x2nrealloc (void *p, size_t *pn, size_t s)
224 /* The approximate size to use for initial small allocation
225 requests, when the invoking code specifies an old size of
226 zero. 64 bytes is the largest "small" request for the
227 GNU C library malloc. */
228 enum { DEFAULT_MXFAST = 64 };
230 n = DEFAULT_MXFAST / s;
236 /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
237 Check for overflow, so that N * S stays in size_t range.
238 The check is slightly conservative, but an exact check isn't
239 worth the trouble. */
240 if ((size_t) -1 / 3 * 2 / s <= n)
246 return xrealloc (p, n * s);
249 /* Return a pointer to a new buffer of N bytes. This is like xmalloc,
250 except it returns char *. */
252 static_inline char *xcharalloc (size_t n)
253 ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1));
255 xcharalloc (size_t n)
257 return XNMALLOC (n, char);
265 /* C++ does not allow conversions from void * to other pointer types
266 without a cast. Use templates to work around the problem when
269 template <typename T> inline T *
270 xrealloc (T *p, size_t s)
272 return (T *) xrealloc ((void *) p, s);
275 template <typename T> inline T *
276 xnrealloc (T *p, size_t n, size_t s)
278 return (T *) xnrealloc ((void *) p, n, s);
281 template <typename T> inline T *
282 x2realloc (T *p, size_t *pn)
284 return (T *) x2realloc ((void *) p, pn);
287 template <typename T> inline T *
288 x2nrealloc (T *p, size_t *pn, size_t s)
290 return (T *) x2nrealloc ((void *) p, pn, s);
293 template <typename T> inline T *
294 xmemdup (T const *p, size_t s)
296 return (T *) xmemdup ((void const *) p, s);
302 #endif /* !XALLOC_H_ */