1*18fd37a7SXin LI /* xmalloc.c -- malloc with out of memory checking
2*18fd37a7SXin LI
3*18fd37a7SXin LI Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003,
4*18fd37a7SXin LI 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
5*18fd37a7SXin LI
6*18fd37a7SXin LI This program is free software; you can redistribute it and/or modify
7*18fd37a7SXin LI it under the terms of the GNU General Public License as published by
8*18fd37a7SXin LI the Free Software Foundation; either version 2, or (at your option)
9*18fd37a7SXin LI any later version.
10*18fd37a7SXin LI
11*18fd37a7SXin LI This program is distributed in the hope that it will be useful,
12*18fd37a7SXin LI but WITHOUT ANY WARRANTY; without even the implied warranty of
13*18fd37a7SXin LI MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*18fd37a7SXin LI GNU General Public License for more details.
15*18fd37a7SXin LI
16*18fd37a7SXin LI You should have received a copy of the GNU General Public License
17*18fd37a7SXin LI along with this program; if not, write to the Free Software Foundation,
18*18fd37a7SXin LI Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19*18fd37a7SXin LI
20*18fd37a7SXin LI #if HAVE_CONFIG_H
21*18fd37a7SXin LI # include <config.h>
22*18fd37a7SXin LI #endif
23*18fd37a7SXin LI
24*18fd37a7SXin LI #include "xalloc.h"
25*18fd37a7SXin LI
26*18fd37a7SXin LI #include <stdlib.h>
27*18fd37a7SXin LI #include <string.h>
28*18fd37a7SXin LI
29*18fd37a7SXin LI #include "gettext.h"
30*18fd37a7SXin LI #define _(msgid) gettext (msgid)
31*18fd37a7SXin LI #define N_(msgid) msgid
32*18fd37a7SXin LI
33*18fd37a7SXin LI #include "error.h"
34*18fd37a7SXin LI #include "exitfail.h"
35*18fd37a7SXin LI
36*18fd37a7SXin LI #ifndef SIZE_MAX
37*18fd37a7SXin LI # define SIZE_MAX ((size_t) -1)
38*18fd37a7SXin LI #endif
39*18fd37a7SXin LI
40*18fd37a7SXin LI #ifndef HAVE_MALLOC
41*18fd37a7SXin LI "you must run the autoconf test for a GNU libc compatible malloc"
42*18fd37a7SXin LI #endif
43*18fd37a7SXin LI
44*18fd37a7SXin LI #ifndef HAVE_REALLOC
45*18fd37a7SXin LI "you must run the autoconf test for a GNU libc compatible realloc"
46*18fd37a7SXin LI #endif
47*18fd37a7SXin LI
48*18fd37a7SXin LI /* If non NULL, call this function when memory is exhausted. */
49*18fd37a7SXin LI void (*xalloc_fail_func) (void) = 0;
50*18fd37a7SXin LI
51*18fd37a7SXin LI /* If XALLOC_FAIL_FUNC is NULL, or does return, display this message
52*18fd37a7SXin LI before exiting when memory is exhausted. Goes through gettext. */
53*18fd37a7SXin LI char const xalloc_msg_memory_exhausted[] = N_("memory exhausted");
54*18fd37a7SXin LI
55*18fd37a7SXin LI void
xalloc_die(void)56*18fd37a7SXin LI xalloc_die (void)
57*18fd37a7SXin LI {
58*18fd37a7SXin LI if (xalloc_fail_func)
59*18fd37a7SXin LI (*xalloc_fail_func) ();
60*18fd37a7SXin LI error (exit_failure, 0, "%s", _(xalloc_msg_memory_exhausted));
61*18fd37a7SXin LI /* The `noreturn' cannot be given to error, since it may return if
62*18fd37a7SXin LI its first argument is 0. To help compilers understand the
63*18fd37a7SXin LI xalloc_die does terminate, call abort. */
64*18fd37a7SXin LI abort ();
65*18fd37a7SXin LI }
66*18fd37a7SXin LI
67*18fd37a7SXin LI /* Allocate an array of N objects, each with S bytes of memory,
68*18fd37a7SXin LI dynamically, with error checking. S must be nonzero. */
69*18fd37a7SXin LI
70*18fd37a7SXin LI static inline void *
xnmalloc_inline(size_t n,size_t s)71*18fd37a7SXin LI xnmalloc_inline (size_t n, size_t s)
72*18fd37a7SXin LI {
73*18fd37a7SXin LI void *p;
74*18fd37a7SXin LI if (xalloc_oversized (n, s) || ! (p = malloc (n * s)))
75*18fd37a7SXin LI xalloc_die ();
76*18fd37a7SXin LI return p;
77*18fd37a7SXin LI }
78*18fd37a7SXin LI
79*18fd37a7SXin LI void *
xnmalloc(size_t n,size_t s)80*18fd37a7SXin LI xnmalloc (size_t n, size_t s)
81*18fd37a7SXin LI {
82*18fd37a7SXin LI return xnmalloc_inline (n, s);
83*18fd37a7SXin LI }
84*18fd37a7SXin LI
85*18fd37a7SXin LI /* Allocate N bytes of memory dynamically, with error checking. */
86*18fd37a7SXin LI
87*18fd37a7SXin LI void *
xmalloc(size_t n)88*18fd37a7SXin LI xmalloc (size_t n)
89*18fd37a7SXin LI {
90*18fd37a7SXin LI return xnmalloc_inline (n, 1);
91*18fd37a7SXin LI }
92*18fd37a7SXin LI
93*18fd37a7SXin LI /* Change the size of an allocated block of memory P to an array of N
94*18fd37a7SXin LI objects each of S bytes, with error checking. S must be nonzero. */
95*18fd37a7SXin LI
96*18fd37a7SXin LI static inline void *
xnrealloc_inline(void * p,size_t n,size_t s)97*18fd37a7SXin LI xnrealloc_inline (void *p, size_t n, size_t s)
98*18fd37a7SXin LI {
99*18fd37a7SXin LI if (xalloc_oversized (n, s) || ! (p = realloc (p, n * s)))
100*18fd37a7SXin LI xalloc_die ();
101*18fd37a7SXin LI return p;
102*18fd37a7SXin LI }
103*18fd37a7SXin LI
104*18fd37a7SXin LI void *
xnrealloc(void * p,size_t n,size_t s)105*18fd37a7SXin LI xnrealloc (void *p, size_t n, size_t s)
106*18fd37a7SXin LI {
107*18fd37a7SXin LI return xnrealloc_inline (p, n, s);
108*18fd37a7SXin LI }
109*18fd37a7SXin LI
110*18fd37a7SXin LI /* Change the size of an allocated block of memory P to N bytes,
111*18fd37a7SXin LI with error checking. */
112*18fd37a7SXin LI
113*18fd37a7SXin LI void *
xrealloc(void * p,size_t n)114*18fd37a7SXin LI xrealloc (void *p, size_t n)
115*18fd37a7SXin LI {
116*18fd37a7SXin LI return xnrealloc_inline (p, n, 1);
117*18fd37a7SXin LI }
118*18fd37a7SXin LI
119*18fd37a7SXin LI
120*18fd37a7SXin LI /* If P is null, allocate a block of at least *PN such objects;
121*18fd37a7SXin LI otherwise, reallocate P so that it contains more than *PN objects
122*18fd37a7SXin LI each of S bytes. *PN must be nonzero unless P is null, and S must
123*18fd37a7SXin LI be nonzero. Set *PN to the new number of objects, and return the
124*18fd37a7SXin LI pointer to the new block. *PN is never set to zero, and the
125*18fd37a7SXin LI returned pointer is never null.
126*18fd37a7SXin LI
127*18fd37a7SXin LI Repeated reallocations are guaranteed to make progress, either by
128*18fd37a7SXin LI allocating an initial block with a nonzero size, or by allocating a
129*18fd37a7SXin LI larger block.
130*18fd37a7SXin LI
131*18fd37a7SXin LI In the following implementation, nonzero sizes are doubled so that
132*18fd37a7SXin LI repeated reallocations have O(N log N) overall cost rather than
133*18fd37a7SXin LI O(N**2) cost, but the specification for this function does not
134*18fd37a7SXin LI guarantee that sizes are doubled.
135*18fd37a7SXin LI
136*18fd37a7SXin LI Here is an example of use:
137*18fd37a7SXin LI
138*18fd37a7SXin LI int *p = NULL;
139*18fd37a7SXin LI size_t used = 0;
140*18fd37a7SXin LI size_t allocated = 0;
141*18fd37a7SXin LI
142*18fd37a7SXin LI void
143*18fd37a7SXin LI append_int (int value)
144*18fd37a7SXin LI {
145*18fd37a7SXin LI if (used == allocated)
146*18fd37a7SXin LI p = x2nrealloc (p, &allocated, sizeof *p);
147*18fd37a7SXin LI p[used++] = value;
148*18fd37a7SXin LI }
149*18fd37a7SXin LI
150*18fd37a7SXin LI This causes x2nrealloc to allocate a block of some nonzero size the
151*18fd37a7SXin LI first time it is called.
152*18fd37a7SXin LI
153*18fd37a7SXin LI To have finer-grained control over the initial size, set *PN to a
154*18fd37a7SXin LI nonzero value before calling this function with P == NULL. For
155*18fd37a7SXin LI example:
156*18fd37a7SXin LI
157*18fd37a7SXin LI int *p = NULL;
158*18fd37a7SXin LI size_t used = 0;
159*18fd37a7SXin LI size_t allocated = 0;
160*18fd37a7SXin LI size_t allocated1 = 1000;
161*18fd37a7SXin LI
162*18fd37a7SXin LI void
163*18fd37a7SXin LI append_int (int value)
164*18fd37a7SXin LI {
165*18fd37a7SXin LI if (used == allocated)
166*18fd37a7SXin LI {
167*18fd37a7SXin LI p = x2nrealloc (p, &allocated1, sizeof *p);
168*18fd37a7SXin LI allocated = allocated1;
169*18fd37a7SXin LI }
170*18fd37a7SXin LI p[used++] = value;
171*18fd37a7SXin LI }
172*18fd37a7SXin LI
173*18fd37a7SXin LI */
174*18fd37a7SXin LI
175*18fd37a7SXin LI static inline void *
x2nrealloc_inline(void * p,size_t * pn,size_t s)176*18fd37a7SXin LI x2nrealloc_inline (void *p, size_t *pn, size_t s)
177*18fd37a7SXin LI {
178*18fd37a7SXin LI size_t n = *pn;
179*18fd37a7SXin LI
180*18fd37a7SXin LI if (! p)
181*18fd37a7SXin LI {
182*18fd37a7SXin LI if (! n)
183*18fd37a7SXin LI {
184*18fd37a7SXin LI /* The approximate size to use for initial small allocation
185*18fd37a7SXin LI requests, when the invoking code specifies an old size of
186*18fd37a7SXin LI zero. 64 bytes is the largest "small" request for the
187*18fd37a7SXin LI GNU C library malloc. */
188*18fd37a7SXin LI enum { DEFAULT_MXFAST = 64 };
189*18fd37a7SXin LI
190*18fd37a7SXin LI n = DEFAULT_MXFAST / s;
191*18fd37a7SXin LI n += !n;
192*18fd37a7SXin LI }
193*18fd37a7SXin LI }
194*18fd37a7SXin LI else
195*18fd37a7SXin LI {
196*18fd37a7SXin LI if (SIZE_MAX / 2 / s < n)
197*18fd37a7SXin LI xalloc_die ();
198*18fd37a7SXin LI n *= 2;
199*18fd37a7SXin LI }
200*18fd37a7SXin LI
201*18fd37a7SXin LI *pn = n;
202*18fd37a7SXin LI return xrealloc (p, n * s);
203*18fd37a7SXin LI }
204*18fd37a7SXin LI
205*18fd37a7SXin LI void *
x2nrealloc(void * p,size_t * pn,size_t s)206*18fd37a7SXin LI x2nrealloc (void *p, size_t *pn, size_t s)
207*18fd37a7SXin LI {
208*18fd37a7SXin LI return x2nrealloc_inline (p, pn, s);
209*18fd37a7SXin LI }
210*18fd37a7SXin LI
211*18fd37a7SXin LI /* If P is null, allocate a block of at least *PN bytes; otherwise,
212*18fd37a7SXin LI reallocate P so that it contains more than *PN bytes. *PN must be
213*18fd37a7SXin LI nonzero unless P is null. Set *PN to the new block's size, and
214*18fd37a7SXin LI return the pointer to the new block. *PN is never set to zero, and
215*18fd37a7SXin LI the returned pointer is never null. */
216*18fd37a7SXin LI
217*18fd37a7SXin LI void *
x2realloc(void * p,size_t * pn)218*18fd37a7SXin LI x2realloc (void *p, size_t *pn)
219*18fd37a7SXin LI {
220*18fd37a7SXin LI return x2nrealloc_inline (p, pn, 1);
221*18fd37a7SXin LI }
222*18fd37a7SXin LI
223*18fd37a7SXin LI /* Allocate S bytes of zeroed memory dynamically, with error checking.
224*18fd37a7SXin LI There's no need for xnzalloc (N, S), since it would be equivalent
225*18fd37a7SXin LI to xcalloc (N, S). */
226*18fd37a7SXin LI
227*18fd37a7SXin LI void *
xzalloc(size_t s)228*18fd37a7SXin LI xzalloc (size_t s)
229*18fd37a7SXin LI {
230*18fd37a7SXin LI return memset (xmalloc (s), 0, s);
231*18fd37a7SXin LI }
232*18fd37a7SXin LI
233*18fd37a7SXin LI /* Allocate zeroed memory for N elements of S bytes, with error
234*18fd37a7SXin LI checking. S must be nonzero. */
235*18fd37a7SXin LI
236*18fd37a7SXin LI void *
xcalloc(size_t n,size_t s)237*18fd37a7SXin LI xcalloc (size_t n, size_t s)
238*18fd37a7SXin LI {
239*18fd37a7SXin LI void *p;
240*18fd37a7SXin LI /* Test for overflow, since some calloc implementations don't have
241*18fd37a7SXin LI proper overflow checks. */
242*18fd37a7SXin LI if (xalloc_oversized (n, s) || ! (p = calloc (n, s)))
243*18fd37a7SXin LI xalloc_die ();
244*18fd37a7SXin LI return p;
245*18fd37a7SXin LI }
246*18fd37a7SXin LI
247*18fd37a7SXin LI /* Clone an object P of size S, with error checking. There's no need
248*18fd37a7SXin LI for xnclone (P, N, S), since xclone (P, N * S) works without any
249*18fd37a7SXin LI need for an arithmetic overflow check. */
250*18fd37a7SXin LI
251*18fd37a7SXin LI void *
xclone(void const * p,size_t s)252*18fd37a7SXin LI xclone (void const *p, size_t s)
253*18fd37a7SXin LI {
254*18fd37a7SXin LI return memcpy (xmalloc (s), p, s);
255*18fd37a7SXin LI }
256