/* xmalloc.c -- malloc with out of memory checking12Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003,31999, 2000, 2002, 2003 Free Software Foundation, Inc.45This program is free software; you can redistribute it and/or modify6it under the terms of the GNU General Public License as published by7the Free Software Foundation; either version 2, or (at your option)8any later version.910This program is distributed in the hope that it will be useful,11but WITHOUT ANY WARRANTY; without even the implied warranty of12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13GNU General Public License for more details.1415You should have received a copy of the GNU General Public License16along with this program; if not, write to the Free Software Foundation,17Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */1819#if HAVE_CONFIG_H20# include <config.h>21#endif2223#include "xalloc.h"2425#include <stdlib.h>26#include <string.h>2728#include "gettext.h"29#define _(msgid) gettext (msgid)30#define N_(msgid) msgid3132#include "error.h"33#include "exitfail.h"3435#ifndef SIZE_MAX36# define SIZE_MAX ((size_t) -1)37#endif3839#ifndef HAVE_MALLOC40"you must run the autoconf test for a GNU libc compatible malloc"41#endif4243#ifndef HAVE_REALLOC44"you must run the autoconf test for a GNU libc compatible realloc"45#endif4647/* If non NULL, call this function when memory is exhausted. */48void (*xalloc_fail_func) (void) = 0;4950/* If XALLOC_FAIL_FUNC is NULL, or does return, display this message51before exiting when memory is exhausted. Goes through gettext. */52char const xalloc_msg_memory_exhausted[] = N_("memory exhausted");5354void55xalloc_die (void)56{57if (xalloc_fail_func)58(*xalloc_fail_func) ();59error (exit_failure, 0, "%s", _(xalloc_msg_memory_exhausted));60/* The `noreturn' cannot be given to error, since it may return if61its first argument is 0. To help compilers understand the62xalloc_die does terminate, call abort. */63abort ();64}6566/* Allocate an array of N objects, each with S bytes of memory,67dynamically, with error checking. S must be nonzero. */6869static inline void *70xnmalloc_inline (size_t n, size_t s)71{72void *p;73if (xalloc_oversized (n, s) || ! (p = malloc (n * s)))74xalloc_die ();75return p;76}7778void *79xnmalloc (size_t n, size_t s)80{81return xnmalloc_inline (n, s);82}8384/* Allocate N bytes of memory dynamically, with error checking. */8586void *87xmalloc (size_t n)88{89return xnmalloc_inline (n, 1);90}9192/* Change the size of an allocated block of memory P to an array of N93objects each of S bytes, with error checking. S must be nonzero. */9495static inline void *96xnrealloc_inline (void *p, size_t n, size_t s)97{98if (xalloc_oversized (n, s) || ! (p = realloc (p, n * s)))99xalloc_die ();100return p;101}102103void *104xnrealloc (void *p, size_t n, size_t s)105{106return xnrealloc_inline (p, n, s);107}108109/* Change the size of an allocated block of memory P to N bytes,110with error checking. */111112void *113xrealloc (void *p, size_t n)114{115return xnrealloc_inline (p, n, 1);116}117118119/* If P is null, allocate a block of at least *PN such objects;120otherwise, reallocate P so that it contains more than *PN objects121each of S bytes. *PN must be nonzero unless P is null, and S must122be nonzero. Set *PN to the new number of objects, and return the123pointer to the new block. *PN is never set to zero, and the124returned pointer is never null.125126Repeated reallocations are guaranteed to make progress, either by127allocating an initial block with a nonzero size, or by allocating a128larger block.129130In the following implementation, nonzero sizes are doubled so that131repeated reallocations have O(N log N) overall cost rather than132O(N**2) cost, but the specification for this function does not133guarantee that sizes are doubled.134135Here is an example of use:136137int *p = NULL;138size_t used = 0;139size_t allocated = 0;140141void142append_int (int value)143{144if (used == allocated)145p = x2nrealloc (p, &allocated, sizeof *p);146p[used++] = value;147}148149This causes x2nrealloc to allocate a block of some nonzero size the150first time it is called.151152To have finer-grained control over the initial size, set *PN to a153nonzero value before calling this function with P == NULL. For154example:155156int *p = NULL;157size_t used = 0;158size_t allocated = 0;159size_t allocated1 = 1000;160161void162append_int (int value)163{164if (used == allocated)165{166p = x2nrealloc (p, &allocated1, sizeof *p);167allocated = allocated1;168}169p[used++] = value;170}171172*/173174static inline void *175x2nrealloc_inline (void *p, size_t *pn, size_t s)176{177size_t n = *pn;178179if (! p)180{181if (! n)182{183/* The approximate size to use for initial small allocation184requests, when the invoking code specifies an old size of185zero. 64 bytes is the largest "small" request for the186GNU C library malloc. */187enum { DEFAULT_MXFAST = 64 };188189n = DEFAULT_MXFAST / s;190n += !n;191}192}193else194{195if (SIZE_MAX / 2 / s < n)196xalloc_die ();197n *= 2;198}199200*pn = n;201return xrealloc (p, n * s);202}203204void *205x2nrealloc (void *p, size_t *pn, size_t s)206{207return x2nrealloc_inline (p, pn, s);208}209210/* If P is null, allocate a block of at least *PN bytes; otherwise,211reallocate P so that it contains more than *PN bytes. *PN must be212nonzero unless P is null. Set *PN to the new block's size, and213return the pointer to the new block. *PN is never set to zero, and214the returned pointer is never null. */215216void *217x2realloc (void *p, size_t *pn)218{219return x2nrealloc_inline (p, pn, 1);220}221222/* Allocate S bytes of zeroed memory dynamically, with error checking.223There's no need for xnzalloc (N, S), since it would be equivalent224to xcalloc (N, S). */225226void *227xzalloc (size_t s)228{229return memset (xmalloc (s), 0, s);230}231232/* Allocate zeroed memory for N elements of S bytes, with error233checking. S must be nonzero. */234235void *236xcalloc (size_t n, size_t s)237{238void *p;239/* Test for overflow, since some calloc implementations don't have240proper overflow checks. */241if (xalloc_oversized (n, s) || ! (p = calloc (n, s)))242xalloc_die ();243return p;244}245246/* Clone an object P of size S, with error checking. There's no need247for xnclone (P, N, S), since xclone (P, N * S) works without any248need for an arithmetic overflow check. */249250void *251xclone (void const *p, size_t s)252{253return memcpy (xmalloc (s), p, s);254}255256257