]> git.cworth.org Git - tar/blob - gnu/xalloc.h
37500ed81d7df0b05afa8b391874f8efa67e08e6
[tar] / gnu / xalloc.h
1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* xalloc.h -- malloc with out-of-memory checking
4
5    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
6    2000, 2003, 2004, 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
7    Inc.
8
9    This program is free software: you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22 #ifndef XALLOC_H_
23 # define XALLOC_H_
24
25 # include <stddef.h>
26
27
28 # ifdef __cplusplus
29 extern "C" {
30 # endif
31
32
33 # ifndef __attribute__
34 #  if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
35 #   define __attribute__(x)
36 #  endif
37 # endif
38
39 # ifndef ATTRIBUTE_NORETURN
40 #  define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
41 # endif
42
43 # ifndef ATTRIBUTE_MALLOC
44 #  if __GNUC__ >= 3
45 #   define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
46 #  else
47 #   define ATTRIBUTE_MALLOC
48 #  endif
49 # endif
50
51 /* This function is always triggered when memory is exhausted.
52    It must be defined by the application, either explicitly
53    or by using gnulib's xalloc-die module.  This is the
54    function to call when one wants the program to die because of a
55    memory allocation failure.  */
56 extern void xalloc_die (void) ATTRIBUTE_NORETURN;
57
58 void *xmalloc (size_t s) ATTRIBUTE_MALLOC;
59 void *xzalloc (size_t s) ATTRIBUTE_MALLOC;
60 void *xcalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
61 void *xrealloc (void *p, size_t s);
62 void *x2realloc (void *p, size_t *pn);
63 void *xmemdup (void const *p, size_t s) ATTRIBUTE_MALLOC;
64 char *xstrdup (char const *str) ATTRIBUTE_MALLOC;
65
66 /* Return 1 if an array of N objects, each of size S, cannot exist due
67    to size arithmetic overflow.  S must be positive and N must be
68    nonnegative.  This is a macro, not an inline function, so that it
69    works correctly even when SIZE_MAX < N.
70
71    By gnulib convention, SIZE_MAX represents overflow in size
72    calculations, so the conservative dividend to use here is
73    SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
74    However, malloc (SIZE_MAX) fails on all known hosts where
75    sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
76    exactly-SIZE_MAX allocations on such hosts; this avoids a test and
77    branch when S is known to be 1.  */
78 # define xalloc_oversized(n, s) \
79     ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
80
81
82 /* In the following macros, T must be an elementary or structure/union or
83    typedef'ed type, or a pointer to such a type.  To apply one of the
84    following macros to a function pointer or array type, you need to typedef
85    it first and use the typedef name.  */
86
87 /* Allocate an object of type T dynamically, with error checking.  */
88 /* extern t *XMALLOC (typename t); */
89 # define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
90
91 /* Allocate memory for N elements of type T, with error checking.  */
92 /* extern t *XNMALLOC (size_t n, typename t); */
93 # define XNMALLOC(n, t) \
94     ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
95
96 /* Allocate an object of type T dynamically, with error checking,
97    and zero it.  */
98 /* extern t *XZALLOC (typename t); */
99 # define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
100
101 /* Allocate memory for N elements of type T, with error checking,
102    and zero it.  */
103 /* extern t *XCALLOC (size_t n, typename t); */
104 # define XCALLOC(n, t) \
105     ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
106
107
108 # if HAVE_INLINE
109 #  define static_inline static inline
110 # else
111 void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
112 void *xnrealloc (void *p, size_t n, size_t s);
113 void *x2nrealloc (void *p, size_t *pn, size_t s);
114 char *xcharalloc (size_t n) ATTRIBUTE_MALLOC;
115 # endif
116
117 # ifdef static_inline
118
119 /* Allocate an array of N objects, each with S bytes of memory,
120    dynamically, with error checking.  S must be nonzero.  */
121
122 static_inline void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
123 static_inline void *
124 xnmalloc (size_t n, size_t s)
125 {
126   if (xalloc_oversized (n, s))
127     xalloc_die ();
128   return xmalloc (n * s);
129 }
130
131 /* Change the size of an allocated block of memory P to an array of N
132    objects each of S bytes, with error checking.  S must be nonzero.  */
133
134 static_inline void *
135 xnrealloc (void *p, size_t n, size_t s)
136 {
137   if (xalloc_oversized (n, s))
138     xalloc_die ();
139   return xrealloc (p, n * s);
140 }
141
142 /* If P is null, allocate a block of at least *PN such objects;
143    otherwise, reallocate P so that it contains more than *PN objects
144    each of S bytes.  *PN must be nonzero unless P is null, and S must
145    be nonzero.  Set *PN to the new number of objects, and return the
146    pointer to the new block.  *PN is never set to zero, and the
147    returned pointer is never null.
148
149    Repeated reallocations are guaranteed to make progress, either by
150    allocating an initial block with a nonzero size, or by allocating a
151    larger block.
152
153    In the following implementation, nonzero sizes are increased by a
154    factor of approximately 1.5 so that repeated reallocations have
155    O(N) overall cost rather than O(N**2) cost, but the
156    specification for this function does not guarantee that rate.
157
158    Here is an example of use:
159
160      int *p = NULL;
161      size_t used = 0;
162      size_t allocated = 0;
163
164      void
165      append_int (int value)
166        {
167          if (used == allocated)
168            p = x2nrealloc (p, &allocated, sizeof *p);
169          p[used++] = value;
170        }
171
172    This causes x2nrealloc to allocate a block of some nonzero size the
173    first time it is called.
174
175    To have finer-grained control over the initial size, set *PN to a
176    nonzero value before calling this function with P == NULL.  For
177    example:
178
179      int *p = NULL;
180      size_t used = 0;
181      size_t allocated = 0;
182      size_t allocated1 = 1000;
183
184      void
185      append_int (int value)
186        {
187          if (used == allocated)
188            {
189              p = x2nrealloc (p, &allocated1, sizeof *p);
190              allocated = allocated1;
191            }
192          p[used++] = value;
193        }
194
195    */
196
197 static_inline void *
198 x2nrealloc (void *p, size_t *pn, size_t s)
199 {
200   size_t n = *pn;
201
202   if (! p)
203     {
204       if (! n)
205         {
206           /* The approximate size to use for initial small allocation
207              requests, when the invoking code specifies an old size of
208              zero.  64 bytes is the largest "small" request for the
209              GNU C library malloc.  */
210           enum { DEFAULT_MXFAST = 64 };
211
212           n = DEFAULT_MXFAST / s;
213           n += !n;
214         }
215     }
216   else
217     {
218       /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
219          Check for overflow, so that N * S stays in size_t range.
220          The check is slightly conservative, but an exact check isn't
221          worth the trouble.  */
222       if ((size_t) -1 / 3 * 2 / s <= n)
223         xalloc_die ();
224       n += (n + 1) / 2;
225     }
226
227   *pn = n;
228   return xrealloc (p, n * s);
229 }
230
231 /* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
232    except it returns char *.  */
233
234 static_inline char *xcharalloc (size_t n) ATTRIBUTE_MALLOC;
235 static_inline char *
236 xcharalloc (size_t n)
237 {
238   return XNMALLOC (n, char);
239 }
240
241 # endif
242
243 # ifdef __cplusplus
244 }
245
246 /* C++ does not allow conversions from void * to other pointer types
247    without a cast.  Use templates to work around the problem when
248    possible.  */
249
250 template <typename T> inline T *
251 xrealloc (T *p, size_t s)
252 {
253   return (T *) xrealloc ((void *) p, s);
254 }
255
256 template <typename T> inline T *
257 xnrealloc (T *p, size_t n, size_t s)
258 {
259   return (T *) xnrealloc ((void *) p, n, s);
260 }
261
262 template <typename T> inline T *
263 x2realloc (T *p, size_t *pn)
264 {
265   return (T *) x2realloc ((void *) p, pn);
266 }
267
268 template <typename T> inline T *
269 x2nrealloc (T *p, size_t *pn, size_t s)
270 {
271   return (T *) x2nrealloc ((void *) p, pn, s);
272 }
273
274 template <typename T> inline T *
275 xmemdup (T const *p, size_t s)
276 {
277   return (T *) xmemdup ((void const *) p, s);
278 }
279
280 # endif
281
282
283 #endif /* !XALLOC_H_ */