b1f6993e3d603b2905bc4aed3198e8f817ad4563
[gnulib.git] / lib / xmalloc.c
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, 2006, 2008 Free Software Foundation,
5    Inc.
6
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include <config.h>
21
22 #if ! HAVE_INLINE
23 # define static_inline
24 #endif
25 #include "xalloc.h"
26 #undef static_inline
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 #ifndef SIZE_MAX
32 # define SIZE_MAX ((size_t) -1)
33 #endif
34
35 /* 1 if calloc is known to be compatible with GNU calloc.  This
36    matters if we are not also using the calloc module, which defines
37    HAVE_CALLOC and supports the GNU API even on non-GNU platforms.  */
38 #if defined HAVE_CALLOC || defined __GLIBC__
39 enum { HAVE_GNU_CALLOC = 1 };
40 #else
41 enum { HAVE_GNU_CALLOC = 0 };
42 #endif
43
44 /* Allocate N bytes of memory dynamically, with error checking.  */
45
46 void *
47 xmalloc (size_t n)
48 {
49   void *p = malloc (n);
50   if (!p && n != 0)
51     xalloc_die ();
52   return p;
53 }
54
55 /* Change the size of an allocated block of memory P to N bytes,
56    with error checking.  */
57
58 void *
59 xrealloc (void *p, size_t n)
60 {
61   p = realloc (p, n);
62   if (!p && n != 0)
63     xalloc_die ();
64   return p;
65 }
66
67 /* If P is null, allocate a block of at least *PN bytes; otherwise,
68    reallocate P so that it contains more than *PN bytes.  *PN must be
69    nonzero unless P is null.  Set *PN to the new block's size, and
70    return the pointer to the new block.  *PN is never set to zero, and
71    the returned pointer is never null.  */
72
73 void *
74 x2realloc (void *p, size_t *pn)
75 {
76   return x2nrealloc (p, pn, 1);
77 }
78
79 /* Allocate S bytes of zeroed memory dynamically, with error checking.
80    There's no need for xnzalloc (N, S), since it would be equivalent
81    to xcalloc (N, S).  */
82
83 void *
84 xzalloc (size_t s)
85 {
86   return memset (xmalloc (s), 0, s);
87 }
88
89 /* Allocate zeroed memory for N elements of S bytes, with error
90    checking.  S must be nonzero.  */
91
92 void *
93 xcalloc (size_t n, size_t s)
94 {
95   void *p;
96   /* Test for overflow, since some calloc implementations don't have
97      proper overflow checks.  But omit overflow and size-zero tests if
98      HAVE_GNU_CALLOC, since GNU calloc catches overflow and never
99      returns NULL if successful.  */
100   if ((! HAVE_GNU_CALLOC && xalloc_oversized (n, s))
101       || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0)))
102     xalloc_die ();
103   return p;
104 }
105
106 /* Clone an object P of size S, with error checking.  There's no need
107    for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
108    need for an arithmetic overflow check.  */
109
110 void *
111 xmemdup (void const *p, size_t s)
112 {
113   return memcpy (xmalloc (s), p, s);
114 }
115
116 /* Clone an object P of size S, with error checking, and include a
117    terminating NUL byte.
118
119    The terminating NUL makes it safe to use strlen or rawmemchr to
120    check for embedded NUL; it also speeds up algorithms such as escape
121    sequence processing on arbitrary memory, by making it always safe
122    to read the byte after the escape character rather than having to
123    check if each escape character is the last byte in the object.  */
124
125 void *
126 xmemdup0 (void const *p, size_t s)
127 {
128   char *result = xcharalloc (s + 1);
129   memcpy (result, p, s);
130   result[s] = 0;
131   return result;
132 }
133
134 /* Clone STRING.  */
135
136 char *
137 xstrdup (char const *string)
138 {
139   return xmemdup (string, strlen (string) + 1);
140 }