1 /* xmalloc.c -- malloc with out of memory checking
3 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003,
4 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
30 #define _(msgid) gettext (msgid)
31 #define N_(msgid) msgid
37 # define SIZE_MAX ((size_t) -1)
40 /* If non NULL, call this function when memory is exhausted. */
41 void (*xalloc_fail_func) (void) = 0;
43 /* If XALLOC_FAIL_FUNC is NULL, or does return, display this message
44 before exiting when memory is exhausted. Goes through gettext. */
45 char const xalloc_msg_memory_exhausted[] = N_("memory exhausted");
51 (*xalloc_fail_func) ();
52 error (exit_failure, 0, "%s", _(xalloc_msg_memory_exhausted));
53 /* The `noreturn' cannot be given to error, since it may return if
54 its first argument is 0. To help compilers understand the
55 xalloc_die does terminate, call abort. */
59 /* Allocate an array of N objects, each with S bytes of memory,
60 dynamically, with error checking. S must be nonzero. */
63 xnmalloc_inline (size_t n, size_t s)
66 if (xalloc_oversized (n, s) || (! (p = malloc (n * s)) && n != 0))
72 xnmalloc (size_t n, size_t s)
74 return xnmalloc_inline (n, s);
77 /* Allocate N bytes of memory dynamically, with error checking. */
82 return xnmalloc_inline (n, 1);
85 /* Change the size of an allocated block of memory P to an array of N
86 objects each of S bytes, with error checking. S must be nonzero. */
89 xnrealloc_inline (void *p, size_t n, size_t s)
91 if (xalloc_oversized (n, s) || (! (p = realloc (p, n * s)) && n != 0))
97 xnrealloc (void *p, size_t n, size_t s)
99 return xnrealloc_inline (p, n, s);
102 /* Change the size of an allocated block of memory P to N bytes,
103 with error checking. */
106 xrealloc (void *p, size_t n)
108 return xnrealloc_inline (p, n, 1);
112 /* If P is null, allocate a block of at least *PN such objects;
113 otherwise, reallocate P so that it contains more than *PN objects
114 each of S bytes. *PN must be nonzero unless P is null, and S must
115 be nonzero. Set *PN to the new number of objects, and return the
116 pointer to the new block. *PN is never set to zero, and the
117 returned pointer is never null.
119 Repeated reallocations are guaranteed to make progress, either by
120 allocating an initial block with a nonzero size, or by allocating a
123 In the following implementation, nonzero sizes are doubled so that
124 repeated reallocations have O(N log N) overall cost rather than
125 O(N**2) cost, but the specification for this function does not
126 guarantee that sizes are doubled.
128 Here is an example of use:
132 size_t allocated = 0;
135 append_int (int value)
137 if (used == allocated)
138 p = x2nrealloc (p, &allocated, sizeof *p);
142 This causes x2nrealloc to allocate a block of some nonzero size the
143 first time it is called.
145 To have finer-grained control over the initial size, set *PN to a
146 nonzero value before calling this function with P == NULL. For
151 size_t allocated = 0;
152 size_t allocated1 = 1000;
155 append_int (int value)
157 if (used == allocated)
159 p = x2nrealloc (p, &allocated1, sizeof *p);
160 allocated = allocated1;
168 x2nrealloc_inline (void *p, size_t *pn, size_t s)
176 /* The approximate size to use for initial small allocation
177 requests, when the invoking code specifies an old size of
178 zero. 64 bytes is the largest "small" request for the
179 GNU C library malloc. */
180 enum { DEFAULT_MXFAST = 64 };
182 n = DEFAULT_MXFAST / s;
188 if (SIZE_MAX / 2 / s < n)
194 return xrealloc (p, n * s);
198 x2nrealloc (void *p, size_t *pn, size_t s)
200 return x2nrealloc_inline (p, pn, s);
203 /* If P is null, allocate a block of at least *PN bytes; otherwise,
204 reallocate P so that it contains more than *PN bytes. *PN must be
205 nonzero unless P is null. Set *PN to the new block's size, and
206 return the pointer to the new block. *PN is never set to zero, and
207 the returned pointer is never null. */
210 x2realloc (void *p, size_t *pn)
212 return x2nrealloc_inline (p, pn, 1);
215 /* Allocate S bytes of zeroed memory dynamically, with error checking.
216 There's no need for xnzalloc (N, S), since it would be equivalent
217 to xcalloc (N, S). */
222 return memset (xmalloc (s), 0, s);
225 /* Allocate zeroed memory for N elements of S bytes, with error
226 checking. S must be nonzero. */
229 xcalloc (size_t n, size_t s)
232 /* Test for overflow, since some calloc implementations don't have
233 proper overflow checks. */
234 if (xalloc_oversized (n, s) || (! (p = calloc (n, s)) && n != 0))
239 /* Clone an object P of size S, with error checking. There's no need
240 for xnclone (P, N, S), since xclone (P, N * S) works without any
241 need for an arithmetic overflow check. */
244 xclone (void const *p, size_t s)
246 return memcpy (xmalloc (s), p, s);