1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* xalloc.h -- malloc with out-of-memory checking
5 Copyright (C) 1990-2000, 2003-2004, 2006-2011 Free Software Foundation, Inc.
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 # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
32 # define _GL_ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
34 # define _GL_ATTRIBUTE_NORETURN /* empty */
38 # define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
40 # define _GL_ATTRIBUTE_MALLOC
43 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
44 # define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
46 # define _GL_ATTRIBUTE_ALLOC_SIZE(args)
49 /* This function is always triggered when memory is exhausted.
50 It must be defined by the application, either explicitly
51 or by using gnulib's xalloc-die module. This is the
52 function to call when one wants the program to die because of a
53 memory allocation failure. */
54 extern void xalloc_die (void) _GL_ATTRIBUTE_NORETURN;
56 void *xmalloc (size_t s)
57 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
58 void *xzalloc (size_t s)
59 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
60 void *xcalloc (size_t n, size_t s)
61 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
62 void *xrealloc (void *p, size_t s)
63 _GL_ATTRIBUTE_ALLOC_SIZE ((2));
64 void *x2realloc (void *p, size_t *pn);
65 void *xmemdup (void const *p, size_t s)
66 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((2));
67 char *xstrdup (char const *str)
70 /* Return 1 if an array of N objects, each of size S, cannot exist due
71 to size arithmetic overflow. S must be positive and N must be
72 nonnegative. This is a macro, not an inline function, so that it
73 works correctly even when SIZE_MAX < N.
75 By gnulib convention, SIZE_MAX represents overflow in size
76 calculations, so the conservative dividend to use here is
77 SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
78 However, malloc (SIZE_MAX) fails on all known hosts where
79 sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
80 exactly-SIZE_MAX allocations on such hosts; this avoids a test and
81 branch when S is known to be 1. */
82 # define xalloc_oversized(n, s) \
83 ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
86 /* In the following macros, T must be an elementary or structure/union or
87 typedef'ed type, or a pointer to such a type. To apply one of the
88 following macros to a function pointer or array type, you need to typedef
89 it first and use the typedef name. */
91 /* Allocate an object of type T dynamically, with error checking. */
92 /* extern t *XMALLOC (typename t); */
93 # define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
95 /* Allocate memory for N elements of type T, with error checking. */
96 /* extern t *XNMALLOC (size_t n, typename t); */
97 # define XNMALLOC(n, t) \
98 ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
100 /* Allocate an object of type T dynamically, with error checking,
102 /* extern t *XZALLOC (typename t); */
103 # define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
105 /* Allocate memory for N elements of type T, with error checking,
107 /* extern t *XCALLOC (size_t n, typename t); */
108 # define XCALLOC(n, t) \
109 ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
113 # define static_inline static inline
115 void *xnmalloc (size_t n, size_t s)
116 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
117 void *xnrealloc (void *p, size_t n, size_t s)
118 _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
119 void *x2nrealloc (void *p, size_t *pn, size_t s);
120 char *xcharalloc (size_t n)
121 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
124 # ifdef static_inline
126 /* Allocate an array of N objects, each with S bytes of memory,
127 dynamically, with error checking. S must be nonzero. */
129 static_inline void *xnmalloc (size_t n, size_t s)
130 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
132 xnmalloc (size_t n, size_t s)
134 if (xalloc_oversized (n, s))
136 return xmalloc (n * s);
139 /* Change the size of an allocated block of memory P to an array of N
140 objects each of S bytes, with error checking. S must be nonzero. */
142 static_inline void *xnrealloc (void *p, size_t n, size_t s)
143 _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
145 xnrealloc (void *p, size_t n, size_t s)
147 if (xalloc_oversized (n, s))
149 return xrealloc (p, n * s);
152 /* If P is null, allocate a block of at least *PN such objects;
153 otherwise, reallocate P so that it contains more than *PN objects
154 each of S bytes. *PN must be nonzero unless P is null, and S must
155 be nonzero. Set *PN to the new number of objects, and return the
156 pointer to the new block. *PN is never set to zero, and the
157 returned pointer is never null.
159 Repeated reallocations are guaranteed to make progress, either by
160 allocating an initial block with a nonzero size, or by allocating a
163 In the following implementation, nonzero sizes are increased by a
164 factor of approximately 1.5 so that repeated reallocations have
165 O(N) overall cost rather than O(N**2) cost, but the
166 specification for this function does not guarantee that rate.
168 Here is an example of use:
172 size_t allocated = 0;
175 append_int (int value)
177 if (used == allocated)
178 p = x2nrealloc (p, &allocated, sizeof *p);
182 This causes x2nrealloc to allocate a block of some nonzero size the
183 first time it is called.
185 To have finer-grained control over the initial size, set *PN to a
186 nonzero value before calling this function with P == NULL. For
191 size_t allocated = 0;
192 size_t allocated1 = 1000;
195 append_int (int value)
197 if (used == allocated)
199 p = x2nrealloc (p, &allocated1, sizeof *p);
200 allocated = allocated1;
208 x2nrealloc (void *p, size_t *pn, size_t s)
216 /* The approximate size to use for initial small allocation
217 requests, when the invoking code specifies an old size of
218 zero. 64 bytes is the largest "small" request for the
219 GNU C library malloc. */
220 enum { DEFAULT_MXFAST = 64 };
222 n = DEFAULT_MXFAST / s;
228 /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
229 Check for overflow, so that N * S stays in size_t range.
230 The check is slightly conservative, but an exact check isn't
231 worth the trouble. */
232 if ((size_t) -1 / 3 * 2 / s <= n)
238 return xrealloc (p, n * s);
241 /* Return a pointer to a new buffer of N bytes. This is like xmalloc,
242 except it returns char *. */
244 static_inline char *xcharalloc (size_t n)
245 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
247 xcharalloc (size_t n)
249 return XNMALLOC (n, char);
257 /* C++ does not allow conversions from void * to other pointer types
258 without a cast. Use templates to work around the problem when
261 template <typename T> inline T *
262 xrealloc (T *p, size_t s)
264 return (T *) xrealloc ((void *) p, s);
267 template <typename T> inline T *
268 xnrealloc (T *p, size_t n, size_t s)
270 return (T *) xnrealloc ((void *) p, n, s);
273 template <typename T> inline T *
274 x2realloc (T *p, size_t *pn)
276 return (T *) x2realloc ((void *) p, pn);
279 template <typename T> inline T *
280 x2nrealloc (T *p, size_t *pn, size_t s)
282 return (T *) x2nrealloc ((void *) p, pn, s);
285 template <typename T> inline T *
286 xmemdup (T const *p, size_t s)
288 return (T *) xmemdup ((void const *) p, s);
294 #endif /* !XALLOC_H_ */