dhcpd-pools  3.0
ISC dhcpd lease usage analyser
xalloc.h
Go to the documentation of this file.
1 /* xalloc.h -- malloc with out-of-memory checking
2 
3  Copyright (C) 1990-2000, 2003-2004, 2006-2017 Free Software Foundation, Inc.
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 
18 #ifndef XALLOC_H_
19 #define XALLOC_H_
20 
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #include "xalloc-oversized.h"
25 
26 #ifndef _GL_INLINE_HEADER_BEGIN
27  #error "Please include config.h first."
28 #endif
30 #ifndef XALLOC_INLINE
31 # define XALLOC_INLINE _GL_INLINE
32 #endif
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 
39 #if __GNUC__ >= 3
40 # define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
41 #else
42 # define _GL_ATTRIBUTE_MALLOC
43 #endif
44 
45 #if ! defined __clang__ && \
46  (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
47 # define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
48 #else
49 # define _GL_ATTRIBUTE_ALLOC_SIZE(args)
50 #endif
51 
52 /* This function is always triggered when memory is exhausted.
53  It must be defined by the application, either explicitly
54  or by using gnulib's xalloc-die module. This is the
55  function to call when one wants the program to die because of a
56  memory allocation failure. */
57 extern _Noreturn void xalloc_die (void);
58 
59 void *xmalloc (size_t s)
61 void *xzalloc (size_t s)
63 void *xcalloc (size_t n, size_t s)
65 void *xrealloc (void *p, size_t s)
67 void *x2realloc (void *p, size_t *pn);
68 void *xmemdup (void const *p, size_t s)
70 char *xstrdup (char const *str)
72 
73 /* In the following macros, T must be an elementary or structure/union or
74  typedef'ed type, or a pointer to such a type. To apply one of the
75  following macros to a function pointer or array type, you need to typedef
76  it first and use the typedef name. */
77 
78 /* Allocate an object of type T dynamically, with error checking. */
79 /* extern t *XMALLOC (typename t); */
80 #define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
81 
82 /* Allocate memory for N elements of type T, with error checking. */
83 /* extern t *XNMALLOC (size_t n, typename t); */
84 #define XNMALLOC(n, t) \
85  ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
86 
87 /* Allocate an object of type T dynamically, with error checking,
88  and zero it. */
89 /* extern t *XZALLOC (typename t); */
90 #define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
91 
92 /* Allocate memory for N elements of type T, with error checking,
93  and zero it. */
94 /* extern t *XCALLOC (size_t n, typename t); */
95 #define XCALLOC(n, t) \
96  ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
97 
98 
99 /* Allocate an array of N objects, each with S bytes of memory,
100  dynamically, with error checking. S must be nonzero. */
101 
102 XALLOC_INLINE void *xnmalloc (size_t n, size_t s)
103  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
104 XALLOC_INLINE void *
105 xnmalloc (size_t n, size_t s)
106 {
107  if (xalloc_oversized (n, s))
108  xalloc_die ();
109  return xmalloc (n * s);
110 }
111 
112 /* Change the size of an allocated block of memory P to an array of N
113  objects each of S bytes, with error checking. S must be nonzero. */
114 
115 XALLOC_INLINE void *xnrealloc (void *p, size_t n, size_t s)
116  _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
117 XALLOC_INLINE void *
118 xnrealloc (void *p, size_t n, size_t s)
119 {
120  if (xalloc_oversized (n, s))
121  xalloc_die ();
122  return xrealloc (p, n * s);
123 }
124 
125 /* If P is null, allocate a block of at least *PN such objects;
126  otherwise, reallocate P so that it contains more than *PN objects
127  each of S bytes. S must be nonzero. Set *PN to the new number of
128  objects, and return the pointer to the new block. *PN is never set
129  to zero, and the returned pointer is never null.
130 
131  Repeated reallocations are guaranteed to make progress, either by
132  allocating an initial block with a nonzero size, or by allocating a
133  larger block.
134 
135  In the following implementation, nonzero sizes are increased by a
136  factor of approximately 1.5 so that repeated reallocations have
137  O(N) overall cost rather than O(N**2) cost, but the
138  specification for this function does not guarantee that rate.
139 
140  Here is an example of use:
141 
142  int *p = NULL;
143  size_t used = 0;
144  size_t allocated = 0;
145 
146  void
147  append_int (int value)
148  {
149  if (used == allocated)
150  p = x2nrealloc (p, &allocated, sizeof *p);
151  p[used++] = value;
152  }
153 
154  This causes x2nrealloc to allocate a block of some nonzero size the
155  first time it is called.
156 
157  To have finer-grained control over the initial size, set *PN to a
158  nonzero value before calling this function with P == NULL. For
159  example:
160 
161  int *p = NULL;
162  size_t used = 0;
163  size_t allocated = 0;
164  size_t allocated1 = 1000;
165 
166  void
167  append_int (int value)
168  {
169  if (used == allocated)
170  {
171  p = x2nrealloc (p, &allocated1, sizeof *p);
172  allocated = allocated1;
173  }
174  p[used++] = value;
175  }
176 
177  */
178 
179 XALLOC_INLINE void *
180 x2nrealloc (void *p, size_t *pn, size_t s)
181 {
182  size_t n = *pn;
183 
184  if (! p)
185  {
186  if (! n)
187  {
188  /* The approximate size to use for initial small allocation
189  requests, when the invoking code specifies an old size of
190  zero. This is the largest "small" request for the GNU C
191  library malloc. */
192  enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
193 
194  n = DEFAULT_MXFAST / s;
195  n += !n;
196  }
197  if (xalloc_oversized (n, s))
198  xalloc_die ();
199  }
200  else
201  {
202  /* Set N = floor (1.5 * N) + 1 so that progress is made even if N == 0.
203  Check for overflow, so that N * S stays in both ptrdiff_t and
204  size_t range. The check may be slightly conservative, but an
205  exact check isn't worth the trouble. */
206  if ((PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX) / 3 * 2 / s
207  <= n)
208  xalloc_die ();
209  n += n / 2 + 1;
210  }
211 
212  *pn = n;
213  return xrealloc (p, n * s);
214 }
215 
216 /* Return a pointer to a new buffer of N bytes. This is like xmalloc,
217  except it returns char *. */
218 
219 XALLOC_INLINE char *xcharalloc (size_t n)
220  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
221 XALLOC_INLINE char *
222 xcharalloc (size_t n)
223 {
224  return XNMALLOC (n, char);
225 }
226 
227 #ifdef __cplusplus
228 }
229 
230 /* C++ does not allow conversions from void * to other pointer types
231  without a cast. Use templates to work around the problem when
232  possible. */
233 
234 template <typename T> inline T *
235 xrealloc (T *p, size_t s)
236 {
237  return (T *) xrealloc ((void *) p, s);
238 }
239 
240 template <typename T> inline T *
241 xnrealloc (T *p, size_t n, size_t s)
242 {
243  return (T *) xnrealloc ((void *) p, n, s);
244 }
245 
246 template <typename T> inline T *
247 x2realloc (T *p, size_t *pn)
248 {
249  return (T *) x2realloc ((void *) p, pn);
250 }
251 
252 template <typename T> inline T *
253 x2nrealloc (T *p, size_t *pn, size_t s)
254 {
255  return (T *) x2nrealloc ((void *) p, pn, s);
256 }
257 
258 template <typename T> inline T *
259 xmemdup (T const *p, size_t s)
260 {
261  return (T *) xmemdup ((void const *) p, s);
262 }
263 
264 #endif
265 
267 
268 #endif /* !XALLOC_H_ */
#define SIZE_MAX
Definition: quotearg.c:52
void * xmalloc(size_t s) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE((1))
Definition: xmalloc.c:39
void void * xrealloc(void *p, size_t s) _GL_ATTRIBUTE_ALLOC_SIZE((2))
Definition: xmalloc.c:51
void * x2realloc(void *p, size_t *pn)
Definition: xmalloc.c:74
#define _Noreturn
Definition: config.h:1695
#define XNMALLOC(n, t)
Definition: xalloc.h:84
#define XALLOC_INLINE
Definition: xalloc.h:31
void * xmemdup(void const *p, size_t s) _GL_ATTRIBUTE_ALLOC_SIZE((2))
Definition: xmalloc.c:111
void * xzalloc(size_t s) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE((1))
Definition: xmalloc.c:84
_Noreturn void xalloc_die(void)
Definition: xalloc-die.c:32
#define PTRDIFF_MAX
Definition: stdint.in.h:529
#define _GL_ATTRIBUTE_ALLOC_SIZE(args)
Definition: xalloc.h:49
XALLOC_INLINE void * xnmalloc(size_t n, size_t s) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE((1
Definition: xalloc.h:105
XALLOC_INLINE void * xnrealloc(void *p, size_t n, size_t s) _GL_ATTRIBUTE_ALLOC_SIZE((2
Definition: xalloc.h:118
#define _GL_INLINE_HEADER_BEGIN
Definition: config.h:1817
#define xalloc_oversized(n, s)
Definition: xalloc-oversized.h:57
#define _GL_ATTRIBUTE_MALLOC
Definition: xalloc.h:42
void * xcalloc(size_t n, size_t s) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE((1
XALLOC_INLINE void * x2nrealloc(void *p, size_t *pn, size_t s)
Definition: xalloc.h:180
char * xstrdup(char const *str) _GL_ATTRIBUTE_MALLOC
Definition: xmalloc.c:119
#define _GL_INLINE_HEADER_END
Definition: config.h:1818
Definition: time_rz.c:45
XALLOC_INLINE char * xcharalloc(size_t n) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE((1))
Definition: xalloc.h:222