1/* xmalloc.c -- malloc with out of memory checking 2 3 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 4 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 5 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) 9 any later version. 10 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. 15 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 19 20#ifdef HAVE_CONFIG_H 21# include <config.h> 22#endif 23 24#include "xalloc.h" 25 26#include <stdlib.h> 27#include <string.h> 28 29#ifndef SIZE_MAX 30# define SIZE_MAX ((size_t) -1) 31#endif 32 33/* 1 if calloc is known to be compatible with GNU calloc. This 34 matters if we are not also using the calloc module, which defines 35 HAVE_CALLOC and supports the GNU API even on non-GNU platforms. */ 36#if defined HAVE_CALLOC || defined __GLIBC__ 37enum { HAVE_GNU_CALLOC = 1 }; 38#else 39enum { HAVE_GNU_CALLOC = 0 }; 40#endif 41 42/* Allocate an array of N objects, each with S bytes of memory, 43 dynamically, with error checking. S must be nonzero. */ 44 45static inline void * 46xnmalloc_inline (size_t n, size_t s) 47{ 48 void *p; 49 if (xalloc_oversized (n, s) || (! (p = malloc (n * s)) && n != 0)) 50 xalloc_die (); 51 return p; 52} 53 54void * 55xnmalloc (size_t n, size_t s) 56{ 57 return xnmalloc_inline (n, s); 58} 59 60/* Allocate N bytes of memory dynamically, with error checking. */ 61 62void * 63xmalloc (size_t n) 64{ 65 return xnmalloc_inline (n, 1); 66} 67 68/* Change the size of an allocated block of memory P to an array of N 69 objects each of S bytes, with error checking. S must be nonzero. */ 70 71static inline void * 72xnrealloc_inline (void *p, size_t n, size_t s) 73{ 74 if (xalloc_oversized (n, s) || (! (p = realloc (p, n * s)) && n != 0)) 75 xalloc_die (); 76 return p; 77} 78 79void * 80xnrealloc (void *p, size_t n, size_t s) 81{ 82 return xnrealloc_inline (p, n, s); 83} 84 85/* Change the size of an allocated block of memory P to N bytes, 86 with error checking. */ 87 88void * 89xrealloc (void *p, size_t n) 90{ 91 return xnrealloc_inline (p, n, 1); 92} 93 94 95/* If P is null, allocate a block of at least *PN such objects; 96 otherwise, reallocate P so that it contains more than *PN objects 97 each of S bytes. *PN must be nonzero unless P is null, and S must 98 be nonzero. Set *PN to the new number of objects, and return the 99 pointer to the new block. *PN is never set to zero, and the 100 returned pointer is never null. 101 102 Repeated reallocations are guaranteed to make progress, either by 103 allocating an initial block with a nonzero size, or by allocating a 104 larger block. 105 106 In the following implementation, nonzero sizes are doubled so that 107 repeated reallocations have O(N log N) overall cost rather than 108 O(N**2) cost, but the specification for this function does not 109 guarantee that sizes are doubled. 110 111 Here is an example of use: 112 113 int *p = NULL; 114 size_t used = 0; 115 size_t allocated = 0; 116 117 void 118 append_int (int value) 119 { 120 if (used == allocated) 121 p = x2nrealloc (p, &allocated, sizeof *p); 122 p[used++] = value; 123 } 124 125 This causes x2nrealloc to allocate a block of some nonzero size the 126 first time it is called. 127 128 To have finer-grained control over the initial size, set *PN to a 129 nonzero value before calling this function with P == NULL. For 130 example: 131 132 int *p = NULL; 133 size_t used = 0; 134 size_t allocated = 0; 135 size_t allocated1 = 1000; 136 137 void 138 append_int (int value) 139 { 140 if (used == allocated) 141 { 142 p = x2nrealloc (p, &allocated1, sizeof *p); 143 allocated = allocated1; 144 } 145 p[used++] = value; 146 } 147 148 */ 149 150static inline void * 151x2nrealloc_inline (void *p, size_t *pn, size_t s) 152{ 153 size_t n = *pn; 154 155 if (! p) 156 { 157 if (! n) 158 { 159 /* The approximate size to use for initial small allocation 160 requests, when the invoking code specifies an old size of 161 zero. 64 bytes is the largest "small" request for the 162 GNU C library malloc. */ 163 enum { DEFAULT_MXFAST = 64 }; 164 165 n = DEFAULT_MXFAST / s; 166 n += !n; 167 } 168 } 169 else 170 { 171 if (SIZE_MAX / 2 / s < n) 172 xalloc_die (); 173 n *= 2; 174 } 175 176 *pn = n; 177 return xrealloc (p, n * s); 178} 179 180void * 181x2nrealloc (void *p, size_t *pn, size_t s) 182{ 183 return x2nrealloc_inline (p, pn, s); 184} 185 186/* If P is null, allocate a block of at least *PN bytes; otherwise, 187 reallocate P so that it contains more than *PN bytes. *PN must be 188 nonzero unless P is null. Set *PN to the new block's size, and 189 return the pointer to the new block. *PN is never set to zero, and 190 the returned pointer is never null. */ 191 192void * 193x2realloc (void *p, size_t *pn) 194{ 195 return x2nrealloc_inline (p, pn, 1); 196} 197 198/* Allocate S bytes of zeroed memory dynamically, with error checking. 199 There's no need for xnzalloc (N, S), since it would be equivalent 200 to xcalloc (N, S). */ 201 202void * 203xzalloc (size_t s) 204{ 205 return memset (xmalloc (s), 0, s); 206} 207 208/* Allocate zeroed memory for N elements of S bytes, with error 209 checking. S must be nonzero. */ 210 211void * 212xcalloc (size_t n, size_t s) 213{ 214 void *p; 215 /* Test for overflow, since some calloc implementations don't have 216 proper overflow checks. But omit overflow and size-zero tests if 217 HAVE_GNU_CALLOC, since GNU calloc catches overflow and never 218 returns NULL if successful. */ 219 if ((! HAVE_GNU_CALLOC && xalloc_oversized (n, s)) 220 || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0))) 221 xalloc_die (); 222 return p; 223} 224 225/* Clone an object P of size S, with error checking. There's no need 226 for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any 227 need for an arithmetic overflow check. */ 228 229void * 230xmemdup (void const *p, size_t s) 231{ 232 return memcpy (xmalloc (s), p, s); 233} 234 235/* Clone STRING. */ 236 237char * 238xstrdup (char const *string) 239{ 240 return xmemdup (string, strlen (string) + 1); 241} 242