Coverage Report

Created: 2026-02-26 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5MM.c
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 */