1 /* xmalloc.c -- malloc with out of memory checking
3 Copyright (C) 1990-2000, 2002-2006, 2008-2021 Free Software Foundation, Inc.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
20 #define XALLOC_INLINE _GL_EXTERN_INLINE
31 static void * _GL_ATTRIBUTE_PURE
39 /* Allocate S bytes of memory dynamically, with error checking. */
44 return nonnull (malloc (s));
50 return nonnull (imalloc (s));
53 /* Change the size of an allocated block of memory P to S bytes,
54 with error checking. */
57 xrealloc (void *p, size_t s)
59 void *r = realloc (p, s);
66 xirealloc (void *p, idx_t s)
68 return nonnull (irealloc (p, s));
71 /* Change the size of an allocated block of memory P to an array of N
72 objects each of S bytes, with error checking. */
75 xreallocarray (void *p, size_t n, size_t s)
77 void *r = reallocarray (p, n, s);
78 if (!r && (!p || (n && s)))
84 xireallocarray (void *p, idx_t n, idx_t s)
86 return nonnull (ireallocarray (p, n, s));
89 /* If P is null, allocate a block of at least *PS bytes; otherwise,
90 reallocate P so that it contains more than *PS bytes. *PS must be
91 nonzero unless P is null. Set *PS to the new block's size, and
92 return the pointer to the new block. *PS is never set to zero, and
93 the returned pointer is never null. */
96 x2realloc (void *p, size_t *ps)
98 return x2nrealloc (p, ps, 1);
101 /* If P is null, allocate a block of at least *PN such objects;
102 otherwise, reallocate P so that it contains more than *PN objects
103 each of S bytes. S must be nonzero. Set *PN to the new number of
104 objects, and return the pointer to the new block. *PN is never set
105 to zero, and the returned pointer is never null.
107 Repeated reallocations are guaranteed to make progress, either by
108 allocating an initial block with a nonzero size, or by allocating a
111 In the following implementation, nonzero sizes are increased by a
112 factor of approximately 1.5 so that repeated reallocations have
113 O(N) overall cost rather than O(N**2) cost, but the
114 specification for this function does not guarantee that rate.
116 Here is an example of use:
120 size_t allocated = 0;
123 append_int (int value)
125 if (used == allocated)
126 p = x2nrealloc (p, &allocated, sizeof *p);
130 This causes x2nrealloc to allocate a block of some nonzero size the
131 first time it is called.
133 To have finer-grained control over the initial size, set *PN to a
134 nonzero value before calling this function with P == NULL. For
139 size_t allocated = 0;
140 size_t allocated1 = 1000;
143 append_int (int value)
145 if (used == allocated)
147 p = x2nrealloc (p, &allocated1, sizeof *p);
148 allocated = allocated1;
156 x2nrealloc (void *p, size_t *pn, size_t s)
164 /* The approximate size to use for initial small allocation
165 requests, when the invoking code specifies an old size of
166 zero. This is the largest "small" request for the GNU C
168 enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
170 n = DEFAULT_MXFAST / s;
176 /* Set N = floor (1.5 * N) + 1 to make progress even if N == 0. */
177 if (INT_ADD_WRAPV (n, (n >> 1) + 1, &n))
181 p = xreallocarray (p, n, s);
186 /* Grow PA, which points to an array of *PN items, and return the
187 location of the reallocated array, updating *PN to reflect its
188 new size. The new array will contain at least N_INCR_MIN more
189 items, but will not contain more than N_MAX items total.
190 S is the size of each item, in bytes.
192 S and N_INCR_MIN must be positive. *PN must be
193 nonnegative. If N_MAX is -1, it is treated as if it were
196 If PA is null, then allocate a new array instead of reallocating
199 Thus, to grow an array A without saving its old contents, do
200 { free (A); A = xpalloc (NULL, &AITEMS, ...); }. */
203 xpalloc (void *pa, idx_t *pn, idx_t n_incr_min, ptrdiff_t n_max, idx_t s)
207 /* The approximate size to use for initial small allocation
208 requests. This is the largest "small" request for the GNU C
210 enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
212 /* If the array is tiny, grow it to about (but no greater than)
213 DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%.
214 Adjust the growth according to three constraints: N_INCR_MIN,
215 N_MAX, and what the C language can represent safely. */
218 if (INT_ADD_WRAPV (n0, n0 >> 1, &n))
220 if (0 <= n_max && n_max < n)
223 /* NBYTES is of a type suitable for holding the count of bytes in an object.
224 This is typically idx_t, but it should be size_t on (theoretical?)
225 platforms where SIZE_MAX < IDX_MAX so xpalloc does not pass
226 values greater than SIZE_MAX to xrealloc. */
227 #if IDX_MAX <= SIZE_MAX
232 idx_t adjusted_nbytes
233 = (INT_MULTIPLY_WRAPV (n, s, &nbytes)
234 ? MIN (IDX_MAX, SIZE_MAX)
235 : nbytes < DEFAULT_MXFAST ? DEFAULT_MXFAST : 0);
238 n = adjusted_nbytes / s;
239 nbytes = adjusted_nbytes - adjusted_nbytes % s;
244 if (n - n0 < n_incr_min
245 && (INT_ADD_WRAPV (n0, n_incr_min, &n)
246 || (0 <= n_max && n_max < n)
247 || INT_MULTIPLY_WRAPV (n, s, &nbytes)))
249 pa = xrealloc (pa, nbytes);
254 /* Allocate S bytes of zeroed memory dynamically, with error checking.
255 There's no need for xnzalloc (N, S), since it would be equivalent
256 to xcalloc (N, S). */
261 return xcalloc (s, 1);
267 return xicalloc (s, 1);
270 /* Allocate zeroed memory for N elements of S bytes, with error
271 checking. S must be nonzero. */
274 xcalloc (size_t n, size_t s)
276 return nonnull (calloc (n, s));
280 xicalloc (idx_t n, idx_t s)
282 return nonnull (icalloc (n, s));
285 /* Clone an object P of size S, with error checking. There's no need
286 for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
287 need for an arithmetic overflow check. */
290 xmemdup (void const *p, size_t s)
292 return memcpy (xmalloc (s), p, s);
296 ximemdup (void const *p, idx_t s)
298 return memcpy (ximalloc (s), p, s);
301 /* Clone an object P of size S, with error checking. Append
302 a terminating NUL byte. */
305 ximemdup0 (void const *p, idx_t s)
307 char *result = ximalloc (s + 1);
309 return memcpy (result, p, s);
315 xstrdup (char const *string)
317 return xmemdup (string, strlen (string) + 1);