Line | Count | Source |
1 | | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
2 | | * Copyright by The HDF Group. * |
3 | | * All rights reserved. * |
4 | | * * |
5 | | * This file is part of HDF5. The full HDF5 copyright notice, including * |
6 | | * terms governing use, modification, and redistribution, is contained in * |
7 | | * the LICENSE file, which can be found at the root of the source code * |
8 | | * distribution tree, or in https://www.hdfgroup.org/licenses. * |
9 | | * If you do not have access to either file, you may request a copy from * |
10 | | * help@hdfgroup.org. * |
11 | | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
12 | | |
13 | | /*------------------------------------------------------------------------- |
14 | | * |
15 | | * Created: H5MM.c |
16 | | * |
17 | | * Purpose: Memory management functions |
18 | | * |
19 | | *------------------------------------------------------------------------- |
20 | | */ |
21 | | |
22 | | /****************/ |
23 | | /* Module Setup */ |
24 | | /****************/ |
25 | | |
26 | | /***********/ |
27 | | /* Headers */ |
28 | | /***********/ |
29 | | #include "H5private.h" /* Generic Functions */ |
30 | | #include "H5Eprivate.h" /* Error handling */ |
31 | | #include "H5MMprivate.h" /* Memory management */ |
32 | | |
33 | | /****************/ |
34 | | /* Local Macros */ |
35 | | /****************/ |
36 | | |
37 | | /******************/ |
38 | | /* Local Typedefs */ |
39 | | /******************/ |
40 | | |
41 | | /********************/ |
42 | | /* Local Prototypes */ |
43 | | /********************/ |
44 | | |
45 | | /*********************/ |
46 | | /* Package Variables */ |
47 | | /*********************/ |
48 | | |
49 | | /*****************************/ |
50 | | /* Library Private Variables */ |
51 | | /*****************************/ |
52 | | |
53 | | /*******************/ |
54 | | /* Local Variables */ |
55 | | /*******************/ |
56 | | |
57 | | /*------------------------------------------------------------------------- |
58 | | * Function: H5MM_realloc |
59 | | * |
60 | | * Purpose: Similar semantics as C89's realloc(). Specifically, the |
61 | | * following calls are equivalent: |
62 | | * |
63 | | * H5MM_realloc(NULL, size) <==> H5MM_malloc(size) |
64 | | * H5MM_realloc(ptr, 0) <==> H5MM_xfree(ptr) |
65 | | * H5MM_realloc(NULL, 0) <==> NULL |
66 | | * |
67 | | * Note that the (NULL, 0) combination is undefined behavior |
68 | | * in the C standard. |
69 | | * |
70 | | * Return: Success: Ptr to new memory if size > 0 |
71 | | * NULL if size is zero |
72 | | * Failure: NULL (input buffer is unchanged on failure) |
73 | | *------------------------------------------------------------------------- |
74 | | */ |
75 | | void * |
76 | | H5MM_realloc(void *mem, size_t size) |
77 | 370 | { |
78 | 370 | void *ret_value = NULL; |
79 | | |
80 | | /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ |
81 | 370 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
82 | | |
83 | 370 | if (NULL == mem && 0 == size) |
84 | | /* Not defined in the standard, return NULL */ |
85 | 0 | ret_value = NULL; |
86 | 370 | else { |
87 | 370 | ret_value = realloc(mem, size); |
88 | | |
89 | | /* Some platforms do not return NULL if size is zero. */ |
90 | 370 | if (0 == size) |
91 | 0 | ret_value = NULL; |
92 | 370 | } |
93 | | |
94 | 370 | FUNC_LEAVE_NOAPI(ret_value) |
95 | 370 | } /* end H5MM_realloc() */ |
96 | | |
97 | | /*------------------------------------------------------------------------- |
98 | | * Function: H5MM_xstrdup |
99 | | * |
100 | | * Purpose: Duplicates a string, including memory allocation. |
101 | | * NULL is an acceptable value for the input string. |
102 | | * |
103 | | * Return: Success: Pointer to a new string (NULL if s is NULL). |
104 | | * Failure: NULL |
105 | | *------------------------------------------------------------------------- |
106 | | */ |
107 | | char * |
108 | | H5MM_xstrdup(const char *s) |
109 | 300 | { |
110 | 300 | char *ret_value = NULL; |
111 | | |
112 | 300 | FUNC_ENTER_NOAPI(NULL) |
113 | | |
114 | 300 | if (s) |
115 | 300 | if (NULL == (ret_value = strdup(s))) |
116 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "string duplication failed"); |
117 | 300 | done: |
118 | 300 | FUNC_LEAVE_NOAPI(ret_value) |
119 | 300 | } /* end H5MM_xstrdup() */ |
120 | | |
121 | | /*------------------------------------------------------------------------- |
122 | | * Function: H5MM_strdup |
123 | | * |
124 | | * Purpose: Duplicates a string, including memory allocation. |
125 | | * NULL is NOT an acceptable value for the input string. |
126 | | * |
127 | | * If the string to be duplicated is the NULL pointer, then |
128 | | * an error will be raised. |
129 | | * |
130 | | * Return: Success: Pointer to a new string |
131 | | * Failure: NULL |
132 | | *------------------------------------------------------------------------- |
133 | | */ |
134 | | char * |
135 | | H5MM_strdup(const char *s) |
136 | 151 | { |
137 | 151 | char *ret_value = NULL; |
138 | | |
139 | 151 | FUNC_ENTER_NOAPI(NULL) |
140 | | |
141 | 151 | if (!s) |
142 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "NULL string not allowed"); |
143 | 151 | if (NULL == (ret_value = strdup(s))) |
144 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "string duplication failed"); |
145 | | |
146 | 151 | done: |
147 | 151 | FUNC_LEAVE_NOAPI(ret_value) |
148 | 151 | } /* end H5MM_strdup() */ |
149 | | |
150 | | /*------------------------------------------------------------------------- |
151 | | * Function: H5MM_strndup |
152 | | * |
153 | | * Purpose: Duplicates a string, including memory allocation, but only |
154 | | * copies at most `n` bytes from the string to be duplicated. |
155 | | * If the string to be duplicated is longer than `n`, only `n` |
156 | | * bytes are copied and a terminating null byte is added. |
157 | | * NULL is NOT an acceptable value for the input string. |
158 | | * |
159 | | * If the string to be duplicated is the NULL pointer, then |
160 | | * an error will be raised. |
161 | | * |
162 | | * Return: Success: Pointer to a new string |
163 | | * Failure: NULL |
164 | | *------------------------------------------------------------------------- |
165 | | */ |
166 | | char * |
167 | | H5MM_strndup(const char *s, size_t n) |
168 | 0 | { |
169 | 0 | char *ret_value = NULL; |
170 | |
|
171 | 0 | FUNC_ENTER_NOAPI(NULL) |
172 | |
|
173 | 0 | if (!s) |
174 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "NULL string not allowed"); |
175 | | |
176 | 0 | if (NULL == (ret_value = HDstrndup(s, n))) |
177 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "string duplication failed"); |
178 | | |
179 | 0 | done: |
180 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
181 | 0 | } /* end H5MM_strndup() */ |
182 | | |
183 | | /*------------------------------------------------------------------------- |
184 | | * Function: H5MM_xfree |
185 | | * |
186 | | * Purpose: Just like free(3) except the return value (always NULL) can |
187 | | * be assigned to the pointer whose memory was just freed: |
188 | | * |
189 | | * thing = H5MM_xfree(thing); |
190 | | * |
191 | | * Return: Success: NULL |
192 | | * Failure: never fails |
193 | | *------------------------------------------------------------------------- |
194 | | */ |
195 | | void * |
196 | | H5MM_xfree(void *mem) |
197 | 305k | { |
198 | | /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ |
199 | 305k | FUNC_ENTER_NOAPI_NOINIT_NOERR |
200 | | |
201 | 305k | free(mem); |
202 | | |
203 | 305k | FUNC_LEAVE_NOAPI(NULL) |
204 | 305k | } /* end H5MM_xfree() */ |
205 | | |
206 | | /*------------------------------------------------------------------------- |
207 | | * Function: H5MM_xfree_const |
208 | | * |
209 | | * Purpose: H5MM_xfree() wrapper that handles const pointers without |
210 | | * warnings. Used for freeing buffers that should be regarded |
211 | | * as const in use but need to be freed when no longer needed. |
212 | | * |
213 | | * Return: Success: NULL |
214 | | * Failure: never fails |
215 | | *------------------------------------------------------------------------- |
216 | | */ |
217 | | void * |
218 | | H5MM_xfree_const(const void *mem) |
219 | 2.38k | { |
220 | | /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ |
221 | 2.38k | FUNC_ENTER_NOAPI_NOINIT_NOERR |
222 | | |
223 | | /* Cast through uintptr_t to de-const memory */ |
224 | 2.38k | H5MM_xfree((void *)(uintptr_t)mem); |
225 | | |
226 | 2.38k | FUNC_LEAVE_NOAPI(NULL) |
227 | 2.38k | } /* end H5MM_xfree_const() */ |
228 | | |
229 | | #ifdef H5MM_DEBUG |
230 | | |
231 | | /*------------------------------------------------------------------------- |
232 | | * Function: H5MM_memcpy |
233 | | * |
234 | | * Purpose: Like memcpy(3) but with sanity checks on the parameters, |
235 | | * particularly buffer overlap. |
236 | | * |
237 | | * Return: Success: pointer to dest |
238 | | * Failure: NULL |
239 | | *------------------------------------------------------------------------- |
240 | | */ |
241 | | void * |
242 | | H5MM_memcpy(void *dest, const void *src, size_t n) |
243 | | { |
244 | | void *ret = NULL; |
245 | | |
246 | | /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ |
247 | | FUNC_ENTER_NOAPI_NOINIT_NOERR |
248 | | |
249 | | assert(dest); |
250 | | assert(src); |
251 | | |
252 | | /* Check for buffer overlap */ |
253 | | assert((char *)dest >= (const char *)src + n || (const char *)src >= (char *)dest + n); |
254 | | |
255 | | /* Copy */ |
256 | | ret = memcpy(dest, src, n); |
257 | | |
258 | | FUNC_LEAVE_NOAPI(ret) |
259 | | |
260 | | } /* end H5MM_memcpy() */ |
261 | | |
262 | | #endif /* H5MM_DEBUG */ |