VirtualBox

source: kBuild/trunk/src/grep/lib/xmalloc.c

Last change on this file was 3529, checked in by bird, 3 years ago

Imported grep 3.7 from grep-3.7.tar.gz (sha256: c22b0cf2d4f6bbe599c902387e8058990e1eee99aef333a203829e5fd3dbb342), applying minimal auto-props.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette