1 /* xmalloc.c -- malloc with out of memory checking 2 3 Copyright (C) 1990-2000, 2002-2006, 2008-2021 Free Software Foundation, Inc. 4 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. 9 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. 14 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/>. */ 17 18 #include <config.h> 19 20 #define XALLOC_INLINE _GL_EXTERN_INLINE 21 22 #include "xalloc.h" 23 24 #include "ialloc.h" 25 #include "intprops.h" 26 #include "minmax.h" 27 28 #include <stdlib.h> 29 #include <string.h> 30 31 static void * _GL_ATTRIBUTE_PURE 32 nonnull (void *p) /* */ 33 { 34 if (!p) 35 xalloc_die (); 36 return p; 37 } 38 39 /* Allocate S bytes of memory dynamically, with error checking. */ 40 41 void * 42 xmalloc (size_t s) /* */ 43 { 44 return nonnull (malloc (s)); 45 } 46 47 void * 48 ximalloc (idx_t s) /* */ 49 { 50 return nonnull (imalloc (s)); 51 } 52 53 char * 54 xcharalloc (size_t n) /* */ 55 { 56 return XNMALLOC (n, char); 57 } 58 59 /* Change the size of an allocated block of memory P to S bytes, 60 with error checking. */ 61 62 void * 63 xrealloc (void *p, size_t s) /* */ 64 { 65 void *r = realloc (p, s); 66 if (!r && (!p || s)) 67 xalloc_die (); 68 return r; 69 } 70 71 void * 72 xirealloc (void *p, idx_t s) /* */ 73 { 74 return nonnull (irealloc (p, s)); 75 } 76 77 /* Change the size of an allocated block of memory P to an array of N 78 objects each of S bytes, with error checking. */ 79 80 void * 81 xreallocarray (void *p, size_t n, size_t s) /* */ 82 { 83 void *r = reallocarray (p, n, s); 84 if (!r && (!p || (n && s))) 85 xalloc_die (); 86 return r; 87 } 88 89 void * 90 xireallocarray (void *p, idx_t n, idx_t s) /* */ 91 { 92 return nonnull (ireallocarray (p, n, s)); 93 } 94 95 /* Allocate an array of N objects, each with S bytes of memory, 96 dynamically, with error checking. S must be nonzero. */ 97 98 void * 99 xnmalloc (size_t n, size_t s) /* */ 100 { 101 return xreallocarray (NULL, n, s); 102 } 103 104 void * 105 xinmalloc (idx_t n, idx_t s) /* */ 106 { 107 return xireallocarray (NULL, n, s); 108 } 109 110 /* If P is null, allocate a block of at least *PS bytes; otherwise, 111 reallocate P so that it contains more than *PS bytes. *PS must be 112 nonzero unless P is null. Set *PS to the new block's size, and 113 return the pointer to the new block. *PS is never set to zero, and 114 the returned pointer is never null. */ 115 116 void * 117 x2realloc (void *p, size_t *ps) /* */ 118 { 119 return x2nrealloc (p, ps, 1); 120 } 121 122 /* If P is null, allocate a block of at least *PN such objects; 123 otherwise, reallocate P so that it contains more than *PN objects 124 each of S bytes. S must be nonzero. Set *PN to the new number of 125 objects, and return the pointer to the new block. *PN is never set 126 to zero, and the returned pointer is never null. 127 128 Repeated reallocations are guaranteed to make progress, either by 129 allocating an initial block with a nonzero size, or by allocating a 130 larger block. 131 132 In the following implementation, nonzero sizes are increased by a 133 factor of approximately 1.5 so that repeated reallocations have 134 O(N) overall cost rather than O(N**2) cost, but the 135 specification for this function does not guarantee that rate. 136 137 Here is an example of use: 138 139 int *p = NULL; 140 size_t used = 0; 141 size_t allocated = 0; 142 143 void 144 append_int (int value) 145 { 146 if (used == allocated) 147 p = x2nrealloc (p, &allocated, sizeof *p); 148 p[used++] = value; 149 } 150 151 This causes x2nrealloc to allocate a block of some nonzero size the 152 first time it is called. 153 154 To have finer-grained control over the initial size, set *PN to a 155 nonzero value before calling this function with P == NULL. For 156 example: 157 158 int *p = NULL; 159 size_t used = 0; 160 size_t allocated = 0; 161 size_t allocated1 = 1000; 162 163 void 164 append_int (int value) 165 { 166 if (used == allocated) 167 { 168 p = x2nrealloc (p, &allocated1, sizeof *p); 169 allocated = allocated1; 170 } 171 p[used++] = value; 172 } 173 174 */ 175 176 void * 177 x2nrealloc (void *p, size_t *pn, size_t s) /* */ 178 { 179 size_t n = *pn; 180 181 if (! p) 182 { 183 if (! n) 184 { 185 /* The approximate size to use for initial small allocation 186 requests, when the invoking code specifies an old size of 187 zero. This is the largest "small" request for the GNU C 188 library malloc. */ 189 enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; 190 191 n = DEFAULT_MXFAST / s; 192 n += !n; 193 } 194 } 195 else 196 { 197 /* Set N = floor (1.5 * N) + 1 to make progress even if N == 0. */ 198 if (INT_ADD_WRAPV (n, (n >> 1) + 1, &n)) 199 xalloc_die (); 200 } 201 202 p = xreallocarray (p, n, s); 203 *pn = n; 204 return p; 205 } 206 207 /* Grow PA, which points to an array of *PN items, and return the 208 location of the reallocated array, updating *PN to reflect its 209 new size. The new array will contain at least N_INCR_MIN more 210 items, but will not contain more than N_MAX items total. 211 S is the size of each item, in bytes. 212 213 S and N_INCR_MIN must be positive. *PN must be 214 nonnegative. If N_MAX is -1, it is treated as if it were 215 infinity. 216 217 If PA is null, then allocate a new array instead of reallocating 218 the old one. 219 220 Thus, to grow an array A without saving its old contents, do 221 { free (A); A = xpalloc (NULL, &AITEMS, ...); }. */ 222 223 void * 224 xpalloc (void *pa, idx_t *pn, idx_t n_incr_min, ptrdiff_t n_max, idx_t s) /* */ 225 { 226 idx_t n0 = *pn; 227 228 /* The approximate size to use for initial small allocation 229 requests. This is the largest "small" request for the GNU C 230 library malloc. */ 231 enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; 232 233 /* If the array is tiny, grow it to about (but no greater than) 234 DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%. 235 Adjust the growth according to three constraints: N_INCR_MIN, 236 N_MAX, and what the C language can represent safely. */ 237 238 idx_t n; 239 if (INT_ADD_WRAPV (n0, n0 >> 1, &n)) 240 n = IDX_MAX; 241 if (0 <= n_max && n_max < n) 242 n = n_max; 243 244 /* NBYTES is of a type suitable for holding the count of bytes in an object. 245 This is typically idx_t, but it should be size_t on (theoretical?) 246 platforms where SIZE_MAX < IDX_MAX so xpalloc does not pass 247 values greater than SIZE_MAX to xrealloc. */ 248 #if IDX_MAX <= SIZE_MAX 249 idx_t nbytes; 250 #else 251 size_t nbytes; 252 #endif 253 idx_t adjusted_nbytes 254 = (INT_MULTIPLY_WRAPV (n, s, &nbytes) 255 ? MIN (IDX_MAX, SIZE_MAX) 256 : nbytes < DEFAULT_MXFAST ? DEFAULT_MXFAST : 0); 257 if (adjusted_nbytes) 258 { 259 n = adjusted_nbytes / s; 260 nbytes = adjusted_nbytes - adjusted_nbytes % s; 261 } 262 263 if (! pa) 264 *pn = 0; 265 if (n - n0 < n_incr_min 266 && (INT_ADD_WRAPV (n0, n_incr_min, &n) 267 || (0 <= n_max && n_max < n) 268 || INT_MULTIPLY_WRAPV (n, s, &nbytes))) 269 xalloc_die (); 270 pa = xrealloc (pa, nbytes); 271 *pn = n; 272 return pa; 273 } 274 275 /* Allocate S bytes of zeroed memory dynamically, with error checking. 276 There's no need for xnzalloc (N, S), since it would be equivalent 277 to xcalloc (N, S). */ 278 279 void * 280 xzalloc (size_t s) /* */ 281 { 282 return xcalloc (s, 1); 283 } 284 285 void * 286 xizalloc (idx_t s) /* */ 287 { 288 return xicalloc (s, 1); 289 } 290 291 /* Allocate zeroed memory for N elements of S bytes, with error 292 checking. S must be nonzero. */ 293 294 void * 295 xcalloc (size_t n, size_t s) /* */ 296 { 297 return nonnull (calloc (n, s)); 298 } 299 300 void * 301 xicalloc (idx_t n, idx_t s) /* */ 302 { 303 return nonnull (icalloc (n, s)); 304 } 305 306 /* Clone an object P of size S, with error checking. There's no need 307 for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any 308 need for an arithmetic overflow check. */ 309 310 void * 311 xmemdup (void const *p, size_t s) /* */ 312 { 313 return memcpy (xmalloc (s), p, s); 314 } 315 316 void * 317 ximemdup (void const *p, idx_t s) /* */ 318 { 319 return memcpy (ximalloc (s), p, s); 320 } 321 322 /* Clone an object P of size S, with error checking. Append 323 a terminating NUL byte. */ 324 325 char * 326 ximemdup0 (void const *p, idx_t s) /* */ 327 { 328 char *result = ximalloc (s + 1); 329 result[s] = 0; 330 return memcpy (result, p, s); 331 } 332 333 /* Clone STRING. */ 334 335 char * 336 xstrdup (char const *string) /* */ 337 { 338 return xmemdup (string, strlen (string) + 1); 339 }