Line | Count | Source (jump to first uncovered line) |
1 | | /* xalloc.h -- malloc with out-of-memory checking |
2 | | |
3 | | Copyright (C) 1990-2000, 2003-2004, 2006-2025 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 | | /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, _Noreturn, |
22 | | _GL_ATTRIBUTE_ALLOC_SIZE, _GL_ATTRIBUTE_MALLOC, |
23 | | _GL_ATTRIBUTE_RETURNS_NONNULL. */ |
24 | | #if !_GL_CONFIG_H_INCLUDED |
25 | | #error "Please include config.h first." |
26 | | #endif |
27 | | |
28 | | #include <stddef.h> |
29 | | #include <stdlib.h> |
30 | | |
31 | | #if GNULIB_XALLOC |
32 | | # include "idx.h" |
33 | | #endif |
34 | | |
35 | | _GL_INLINE_HEADER_BEGIN |
36 | | #ifndef XALLOC_INLINE |
37 | | # define XALLOC_INLINE _GL_INLINE |
38 | | #endif |
39 | | |
40 | | |
41 | | #ifdef __cplusplus |
42 | | extern "C" { |
43 | | #endif |
44 | | |
45 | | |
46 | | #if GNULIB_XALLOC_DIE |
47 | | |
48 | | /* This function is always triggered when memory is exhausted. |
49 | | It must be defined by the application, either explicitly |
50 | | or by using gnulib's xalloc-die module. This is the |
51 | | function to call when one wants the program to die because of a |
52 | | memory allocation failure. */ |
53 | | _Noreturn void xalloc_die (void); |
54 | | |
55 | | #endif /* GNULIB_XALLOC_DIE */ |
56 | | |
57 | | #if GNULIB_XALLOC |
58 | | |
59 | | void *xmalloc (size_t s) |
60 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
61 | | _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
62 | | void *ximalloc (idx_t s) |
63 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
64 | | _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
65 | | void *xinmalloc (idx_t n, idx_t s) |
66 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
67 | | _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
68 | | void *xzalloc (size_t s) |
69 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
70 | | _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
71 | | void *xizalloc (idx_t s) |
72 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
73 | | _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
74 | | void *xcalloc (size_t n, size_t s) |
75 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
76 | | _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
77 | | void *xicalloc (idx_t n, idx_t s) |
78 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
79 | | _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
80 | | void *xrealloc (void *p, size_t s) |
81 | | _GL_ATTRIBUTE_ALLOC_SIZE ((2)); |
82 | | void *xirealloc (void *p, idx_t s) |
83 | | _GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
84 | | void *xreallocarray (void *p, size_t n, size_t s) |
85 | | _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); |
86 | | void *xireallocarray (void *p, idx_t n, idx_t s) |
87 | | _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
88 | | void *x2realloc (void *p, size_t *ps) /* superseded by xpalloc */ |
89 | | _GL_ATTRIBUTE_RETURNS_NONNULL; |
90 | | void *x2nrealloc (void *p, size_t *pn, size_t s) /* superseded by xpalloc */ |
91 | | _GL_ATTRIBUTE_RETURNS_NONNULL; |
92 | | void *xpalloc (void *pa, idx_t *pn, idx_t n_incr_min, ptrdiff_t n_max, idx_t s) |
93 | | _GL_ATTRIBUTE_RETURNS_NONNULL; |
94 | | void *xmemdup (void const *p, size_t s) |
95 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
96 | | _GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
97 | | void *ximemdup (void const *p, idx_t s) |
98 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
99 | | _GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
100 | | char *ximemdup0 (void const *p, idx_t s) |
101 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
102 | | _GL_ATTRIBUTE_RETURNS_NONNULL; |
103 | | char *xstrdup (char const *str) |
104 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
105 | | _GL_ATTRIBUTE_RETURNS_NONNULL; |
106 | | |
107 | | /* In the following macros, T must be an elementary or structure/union or |
108 | | typedef'ed type, or a pointer to such a type. To apply one of the |
109 | | following macros to a function pointer or array type, you need to typedef |
110 | | it first and use the typedef name. */ |
111 | | |
112 | | /* Allocate an object of type T dynamically, with error checking. */ |
113 | | /* extern t *XMALLOC (typename t); */ |
114 | | # define XMALLOC(t) ((t *) xmalloc (sizeof (t))) |
115 | | |
116 | | /* Allocate memory for N elements of type T, with error checking. */ |
117 | | /* extern t *XNMALLOC (size_t n, typename t); */ |
118 | | # define XNMALLOC(n, t) \ |
119 | 0 | ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t)))) |
120 | | |
121 | | /* Allocate an object of type T dynamically, with error checking, |
122 | | and zero it. */ |
123 | | /* extern t *XZALLOC (typename t); */ |
124 | | # define XZALLOC(t) ((t *) xzalloc (sizeof (t))) |
125 | | |
126 | | /* Allocate memory for N elements of type T, with error checking, |
127 | | and zero it. */ |
128 | | /* extern t *XCALLOC (size_t n, typename t); */ |
129 | | # define XCALLOC(n, t) \ |
130 | | ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))) |
131 | | |
132 | | |
133 | | /* Allocate an array of N objects, each with S bytes of memory, |
134 | | dynamically, with error checking. S must be nonzero. */ |
135 | | |
136 | | void *xnmalloc (size_t n, size_t s) |
137 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
138 | | _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
139 | | |
140 | | /* FIXME: Deprecate this in favor of xreallocarray? */ |
141 | | /* Change the size of an allocated block of memory P to an array of N |
142 | | objects each of S bytes, with error checking. S must be nonzero. */ |
143 | | |
144 | | XALLOC_INLINE void *xnrealloc (void *p, size_t n, size_t s) |
145 | | _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); |
146 | | XALLOC_INLINE void * |
147 | | xnrealloc (void *p, size_t n, size_t s) |
148 | 0 | { |
149 | 0 | return xreallocarray (p, n, s); |
150 | 0 | } |
151 | | |
152 | | /* Return a pointer to a new buffer of N bytes. This is like xmalloc, |
153 | | except it returns char *. */ |
154 | | |
155 | | char *xcharalloc (size_t n) |
156 | | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
157 | | _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
158 | | |
159 | | #endif /* GNULIB_XALLOC */ |
160 | | |
161 | | |
162 | | #ifdef __cplusplus |
163 | | } |
164 | | #endif |
165 | | |
166 | | |
167 | | #if GNULIB_XALLOC && defined __cplusplus |
168 | | |
169 | | /* C++ does not allow conversions from void * to other pointer types |
170 | | without a cast. Use templates to work around the problem when |
171 | | possible. */ |
172 | | |
173 | | template <typename T> inline T * |
174 | | xrealloc (T *p, size_t s) |
175 | | { |
176 | | return (T *) xrealloc ((void *) p, s); |
177 | | } |
178 | | |
179 | | template <typename T> inline T * |
180 | | xreallocarray (T *p, size_t n, size_t s) |
181 | | { |
182 | | return (T *) xreallocarray ((void *) p, n, s); |
183 | | } |
184 | | |
185 | | /* FIXME: Deprecate this in favor of xreallocarray? */ |
186 | | template <typename T> inline T * |
187 | | xnrealloc (T *p, size_t n, size_t s) |
188 | | { |
189 | | return xreallocarray (p, n, s); |
190 | | } |
191 | | |
192 | | template <typename T> inline T * |
193 | | x2realloc (T *p, size_t *pn) |
194 | | { |
195 | | return (T *) x2realloc ((void *) p, pn); |
196 | | } |
197 | | |
198 | | template <typename T> inline T * |
199 | | x2nrealloc (T *p, size_t *pn, size_t s) |
200 | | { |
201 | | return (T *) x2nrealloc ((void *) p, pn, s); |
202 | | } |
203 | | |
204 | | template <typename T> inline T * |
205 | | xmemdup (T const *p, size_t s) |
206 | | { |
207 | | return (T *) xmemdup ((void const *) p, s); |
208 | | } |
209 | | |
210 | | #endif /* GNULIB_XALLOC && C++ */ |
211 | | |
212 | | |
213 | | _GL_INLINE_HEADER_END |
214 | | |
215 | | #endif /* !XALLOC_H_ */ |