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
/* 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) ATTRIBUTE_NORETURN;
56
void *xmalloc (size_t s) ATTRIBUTE_MALLOC;
57
void *xzalloc (size_t s) ATTRIBUTE_MALLOC;
58
void *xcalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
59
void *xrealloc (void *p, size_t s);
60
void *x2realloc (void *p, size_t *pn);
61
void *xmemdup (void const *p, size_t s) ATTRIBUTE_MALLOC;
62
char *xstrdup (char const *str) ATTRIBUTE_MALLOC;
64
/* Return 1 if an array of N objects, each of size S, cannot exist due
65
to size arithmetic overflow. S must be positive and N must be
66
nonnegative. This is a macro, not an inline function, so that it
67
works correctly even when SIZE_MAX < N.
69
By gnulib convention, SIZE_MAX represents overflow in size
70
calculations, so the conservative dividend to use here is
71
SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
72
However, malloc (SIZE_MAX) fails on all known hosts where
73
sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
74
exactly-SIZE_MAX allocations on such hosts; this avoids a test and
75
branch when S is known to be 1. */
76
# define xalloc_oversized(n, s) \
77
((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
80
/* In the following macros, T must be an elementary or structure/union or
81
typedef'ed type, or a pointer to such a type. To apply one of the
82
following macros to a function pointer or array type, you need to typedef
83
it first and use the typedef name. */
85
/* Allocate an object of type T dynamically, with error checking. */
86
/* extern t *XMALLOC (typename t); */
87
# define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
89
/* Allocate memory for N elements of type T, with error checking. */
90
/* extern t *XNMALLOC (size_t n, typename t); */
91
# define XNMALLOC(n, t) \
92
((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
94
/* Allocate an object of type T dynamically, with error checking,
96
/* extern t *XZALLOC (typename t); */
97
# define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
99
/* Allocate memory for N elements of type T, with error checking,
101
/* extern t *XCALLOC (size_t n, typename t); */
102
# define XCALLOC(n, t) \
103
((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
106
* Gawk uses this file only to keep dfa.c happy.
107
* We're therefore safe in manually defining HAVE_INLINE to
108
* make the !@#$%^&*() thing just work.
111
#define HAVE_INLINE 1 /* so there. nyah, nyah, nyah. */
115
# define static_inline static inline
117
void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
118
void *xnrealloc (void *p, size_t n, size_t s);
119
void *x2nrealloc (void *p, size_t *pn, size_t s);
120
char *xcharalloc (size_t n) ATTRIBUTE_MALLOC;
123
# ifdef static_inline
125
/* Allocate an array of N objects, each with S bytes of memory,
126
dynamically, with error checking. S must be nonzero. */
128
static_inline void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
130
xnmalloc (size_t n, size_t s)
132
if (xalloc_oversized (n, s))
134
return xmalloc (n * s);
139
extern void r_fatal(const char *msg, ...) ATTRIBUTE_NORETURN ;
141
/* Allocate an array of N objects, each with S bytes of memory,
142
dynamically, with error checking. S must be nonzero.
143
Clear the contents afterwards. */
146
xcalloc(size_t nmemb, size_t size)
148
void *p = xmalloc (nmemb * size);
149
memset(p, '\0', nmemb * size);
153
/* Reallocate a pointer to a new size, with error checking. */
156
xrealloc(void *p, size_t size)
158
void *new_p = realloc(p, size);
165
/* xalloc_die --- fatal error message when malloc fails, needed by dfa.c */
170
r_fatal(_("xalloc: malloc failed: %s"), strerror(errno));
173
/* Clone an object P of size S, with error checking. There's no need
174
for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
175
need for an arithmetic overflow check. */
178
xmemdup (void const *p, size_t s)
180
return memcpy (xmalloc (s), p, s);
183
/* xstrdup --- strdup and die if fails */
184
char *xstrdup(const char *s)
190
r_fatal(_("xstrdup: null parameter"));
193
p = xmemdup(s, l + 1);
200
/* Change the size of an allocated block of memory P to an array of N
201
objects each of S bytes, with error checking. S must be nonzero. */
204
xnrealloc (void *p, size_t n, size_t s)
206
if (xalloc_oversized (n, s))
208
return xrealloc (p, n * s);
211
/* If P is null, allocate a block of at least *PN such objects;
212
otherwise, reallocate P so that it contains more than *PN objects
213
each of S bytes. *PN must be nonzero unless P is null, and S must
214
be nonzero. Set *PN to the new number of objects, and return the
215
pointer to the new block. *PN is never set to zero, and the
216
returned pointer is never null.
218
Repeated reallocations are guaranteed to make progress, either by
219
allocating an initial block with a nonzero size, or by allocating a
222
In the following implementation, nonzero sizes are increased by a
223
factor of approximately 1.5 so that repeated reallocations have
224
O(N) overall cost rather than O(N**2) cost, but the
225
specification for this function does not guarantee that rate.
227
Here is an example of use:
231
size_t allocated = 0;
234
append_int (int value)
236
if (used == allocated)
237
p = x2nrealloc (p, &allocated, sizeof *p);
241
This causes x2nrealloc to allocate a block of some nonzero size the
242
first time it is called.
244
To have finer-grained control over the initial size, set *PN to a
245
nonzero value before calling this function with P == NULL. For
250
size_t allocated = 0;
251
size_t allocated1 = 1000;
254
append_int (int value)
256
if (used == allocated)
258
p = x2nrealloc (p, &allocated1, sizeof *p);
259
allocated = allocated1;
267
x2nrealloc (void *p, size_t *pn, size_t s)
275
/* The approximate size to use for initial small allocation
276
requests, when the invoking code specifies an old size of
277
zero. 64 bytes is the largest "small" request for the
278
GNU C library malloc. */
279
enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
281
n = DEFAULT_MXFAST / s;
287
/* Set N = ceil (1.5 * N) so that progress is made if N == 1.
288
Check for overflow, so that N * S stays in size_t range.
289
The check is slightly conservative, but an exact check isn't
290
worth the trouble. */
291
if ((size_t) -1 / 3 * 2 / s <= n)
297
return xrealloc (p, n * s);
300
/* Return a pointer to a new buffer of N bytes. This is like xmalloc,
301
except it returns char *. */
303
static_inline char *xcharalloc (size_t n) ATTRIBUTE_MALLOC;
305
xcharalloc (size_t n)
307
return XNMALLOC (n, char);
310
/* Allocate S bytes of zeroed memory dynamically, with error checking.
311
There's no need for xnzalloc (N, S), since it would be equivalent
312
to xcalloc (N, S). */
317
return memset (xmalloc (s), 0, s);
325
/* C++ does not allow conversions from void * to other pointer types
326
without a cast. Use templates to work around the problem when
329
template <typename T> inline T *
330
xrealloc (T *p, size_t s)
332
return (T *) xrealloc ((void *) p, s);
335
template <typename T> inline T *
336
xnrealloc (T *p, size_t n, size_t s)
338
return (T *) xnrealloc ((void *) p, n, s);
341
template <typename T> inline T *
342
x2realloc (T *p, size_t *pn)
344
return (T *) x2realloc ((void *) p, pn);
347
template <typename T> inline T *
348
x2nrealloc (T *p, size_t *pn, size_t s)
350
return (T *) x2nrealloc ((void *) p, pn, s);
353
template <typename T> inline T *
354
xmemdup (T const *p, size_t s)
356
return (T *) xmemdup ((void const *) p, s);
362
#endif /* !XALLOC_H_ */