Branch data Line data Source code
1 : : /* GLIB - Library of useful routines for C programming
2 : : * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * This library is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General Public
17 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : */
19 : :
20 : : /*
21 : : * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 : : * file for a list of people on the GLib Team. See the ChangeLog
23 : : * files for a list of changes. These files are distributed with
24 : : * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 : : */
26 : :
27 : : /*
28 : : * MT safe
29 : : */
30 : :
31 : : #include "config.h"
32 : :
33 : : #include "gmem.h"
34 : :
35 : : #if defined(HAVE_POSIX_MEMALIGN) && !defined(_XOPEN_SOURCE)
36 : : # define _XOPEN_SOURCE 600
37 : : #endif
38 : :
39 : : #if defined(HAVE_MEMALIGN) || defined(HAVE__ALIGNED_MALLOC)
40 : : /* Required for _aligned_malloc() and _aligned_free() on Windows */
41 : : #include <malloc.h>
42 : : #endif
43 : :
44 : : #ifdef HAVE__ALIGNED_MALLOC
45 : : /* _aligned_malloc() takes parameters of aligned_malloc() in reverse order */
46 : : # define aligned_alloc(alignment, size) _aligned_malloc (size, alignment)
47 : :
48 : : /* _aligned_malloc()'ed memory must be freed by _align_free() on MSVC */
49 : : # define aligned_free(x) _aligned_free (x)
50 : : #else
51 : : # define aligned_free(x) free (x)
52 : : #endif
53 : :
54 : : #include <stdlib.h>
55 : : #include <string.h>
56 : : #include <signal.h>
57 : :
58 : : #include "gslice.h"
59 : : #include "gbacktrace.h"
60 : : #include "gtestutils.h"
61 : : #include "gthread.h"
62 : : #include "glib_trace.h"
63 : :
64 : : /* notes on macros:
65 : : * having G_DISABLE_CHECKS defined disables use of glib_mem_profiler_table and
66 : : * g_mem_profile().
67 : : * If g_mem_gc_friendly is TRUE, freed memory should be 0-wiped.
68 : : */
69 : :
70 : : /* --- variables --- */
71 : : static GMemVTable glib_mem_vtable = {
72 : : malloc,
73 : : realloc,
74 : : free,
75 : : calloc,
76 : : malloc,
77 : : realloc,
78 : : };
79 : :
80 : : /* --- functions --- */
81 : : /**
82 : : * g_malloc:
83 : : * @n_bytes: the number of bytes to allocate
84 : : *
85 : : * Allocates @n_bytes bytes of memory.
86 : : * If @n_bytes is 0 it returns %NULL.
87 : : *
88 : : * If the allocation fails (because the system is out of memory),
89 : : * the program is terminated.
90 : : *
91 : : * Returns: a pointer to the allocated memory
92 : : */
93 : : gpointer
94 : 70934377 : g_malloc (gsize n_bytes)
95 : : {
96 [ + + ]: 70934377 : if (G_LIKELY (n_bytes))
97 : : {
98 : : gpointer mem;
99 : :
100 : 70919048 : mem = malloc (n_bytes);
101 : 70919048 : TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 0));
102 [ + - ]: 70919048 : if (mem)
103 : 70919048 : return mem;
104 : :
105 : 0 : g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
106 : : G_STRLOC, n_bytes);
107 : : }
108 : :
109 : 15329 : TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 0, 0));
110 : :
111 : 15329 : return NULL;
112 : : }
113 : :
114 : : /**
115 : : * g_malloc0:
116 : : * @n_bytes: the number of bytes to allocate
117 : : *
118 : : * Allocates @n_bytes bytes of memory, initialized to 0's.
119 : : * If @n_bytes is 0 it returns %NULL.
120 : : *
121 : : * If the allocation fails (because the system is out of memory),
122 : : * the program is terminated.
123 : : *
124 : : * Returns: a pointer to the allocated memory
125 : : */
126 : : gpointer
127 : 15120925 : g_malloc0 (gsize n_bytes)
128 : : {
129 [ + + ]: 15120925 : if (G_LIKELY (n_bytes))
130 : : {
131 : : gpointer mem;
132 : :
133 : 15120632 : mem = calloc (1, n_bytes);
134 : 15120632 : TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 1, 0));
135 [ + - ]: 15120632 : if (mem)
136 : 15120632 : return mem;
137 : :
138 : 0 : g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
139 : : G_STRLOC, n_bytes);
140 : : }
141 : :
142 : 293 : TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 1, 0));
143 : :
144 : 293 : return NULL;
145 : : }
146 : :
147 : : /**
148 : : * g_realloc:
149 : : * @mem: (nullable): the memory to reallocate
150 : : * @n_bytes: new size of the memory in bytes
151 : : *
152 : : * Reallocates the memory pointed to by @mem, so that it now has space for
153 : : * @n_bytes bytes of memory. It returns the new address of the memory, which may
154 : : * have been moved. @mem may be %NULL, in which case it's considered to
155 : : * have zero-length. @n_bytes may be 0, in which case %NULL will be returned
156 : : * and @mem will be freed unless it is %NULL.
157 : : *
158 : : * If the allocation fails (because the system is out of memory),
159 : : * the program is terminated.
160 : : *
161 : : * Returns: the new address of the allocated memory
162 : : */
163 : : gpointer
164 : 3654937 : g_realloc (gpointer mem,
165 : : gsize n_bytes)
166 : : {
167 : : gpointer newmem;
168 : :
169 [ + + ]: 3654937 : if (G_LIKELY (n_bytes))
170 : : {
171 : 3652510 : newmem = realloc (mem, n_bytes);
172 : 3652510 : TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 0));
173 [ + - ]: 3652510 : if (newmem)
174 : 3652510 : return newmem;
175 : :
176 : 0 : g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
177 : : G_STRLOC, n_bytes);
178 : : }
179 : :
180 : 2427 : free (mem);
181 : :
182 : 2427 : TRACE (GLIB_MEM_REALLOC((void*) NULL, (void*)mem, 0, 0));
183 : :
184 : 2427 : return NULL;
185 : : }
186 : :
187 : : /**
188 : : * g_free:
189 : : * @mem: (nullable): the memory to free
190 : : *
191 : : * Frees the memory pointed to by @mem.
192 : : *
193 : : * If you know the allocated size of @mem, calling g_free_sized() may be faster,
194 : : * depending on the libc implementation in use.
195 : : *
196 : : * Starting from GLib 2.78, this may happen automatically in case a GCC
197 : : * compatible compiler is used with some optimization level and the allocated
198 : : * size is known at compile time (see [documentation of
199 : : * `__builtin_object_size()`](https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html)
200 : : * to understand its caveats).
201 : : *
202 : : * If @mem is %NULL it simply returns, so there is no need to check @mem
203 : : * against %NULL before calling this function.
204 : : */
205 : : void
206 : 59537430 : (g_free) (gpointer mem)
207 : : {
208 : 59537430 : free (mem);
209 : 59537430 : TRACE(GLIB_MEM_FREE((void*) mem));
210 : 59537430 : }
211 : :
212 : : /**
213 : : * g_free_sized:
214 : : * @mem: (nullable): the memory to free
215 : : * @size: size of @mem, in bytes
216 : : *
217 : : * Frees the memory pointed to by @mem, assuming it is has the given @size.
218 : : *
219 : : * If @mem is %NULL this is a no-op (and @size is ignored).
220 : : *
221 : : * It is an error if @size doesn’t match the size passed when @mem was
222 : : * allocated. @size is passed to this function to allow optimizations in the
223 : : * allocator. If you don’t know the allocation size, use g_free() instead.
224 : : *
225 : : * In case a GCC compatible compiler is used, this function may be used
226 : : * automatically via g_free() if the allocated size is known at compile time,
227 : : * since GLib 2.78.
228 : : *
229 : : * Since: 2.76
230 : : */
231 : : void
232 : 48593936 : g_free_sized (void *mem,
233 : : size_t size)
234 : : {
235 : : #ifdef HAVE_FREE_SIZED
236 : : free_sized (mem, size);
237 : : #else
238 : 48593936 : free (mem);
239 : : #endif
240 : 48593936 : TRACE (GLIB_MEM_FREE ((void*) mem));
241 : 48593936 : }
242 : :
243 : : /**
244 : : * g_clear_pointer: (skip)
245 : : * @pp: (nullable) (not optional) (inout) (transfer full): a pointer to a
246 : : * variable, struct member etc. holding a pointer
247 : : * @destroy: a function to which a gpointer can be passed, to destroy *@pp
248 : : *
249 : : * Clears a reference to a variable.
250 : : *
251 : : * @pp must not be %NULL.
252 : : *
253 : : * If the reference is %NULL then this function does nothing.
254 : : * Otherwise, the variable is destroyed using @destroy and the
255 : : * pointer is set to %NULL.
256 : : *
257 : : * A macro is also included that allows this function to be used without
258 : : * pointer casts. This will mask any warnings about incompatible function types
259 : : * or calling conventions, so you must ensure that your @destroy function is
260 : : * compatible with being called as `GDestroyNotify` using the standard calling
261 : : * convention for the platform that GLib was compiled for; otherwise the program
262 : : * will experience undefined behaviour.
263 : : *
264 : : * Since: 2.34
265 : : **/
266 : : #undef g_clear_pointer
267 : : void
268 : 5 : g_clear_pointer (gpointer *pp,
269 : : GDestroyNotify destroy)
270 : : {
271 : : gpointer _p;
272 : :
273 : 5 : _p = *pp;
274 [ + - ]: 5 : if (_p)
275 : : {
276 : 5 : *pp = NULL;
277 : 5 : destroy (_p);
278 : : }
279 : 5 : }
280 : :
281 : : /**
282 : : * g_try_malloc:
283 : : * @n_bytes: number of bytes to allocate.
284 : : *
285 : : * Attempts to allocate @n_bytes, and returns %NULL on failure.
286 : : * Contrast with g_malloc(), which aborts the program on failure.
287 : : *
288 : : * Returns: the allocated memory, or %NULL.
289 : : */
290 : : gpointer
291 : 387161 : g_try_malloc (gsize n_bytes)
292 : : {
293 : : gpointer mem;
294 : :
295 [ + + ]: 387161 : if (G_LIKELY (n_bytes))
296 : 387156 : mem = malloc (n_bytes);
297 : : else
298 : 5 : mem = NULL;
299 : :
300 : 387161 : TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 1));
301 : :
302 : 387161 : return mem;
303 : : }
304 : :
305 : : /**
306 : : * g_try_malloc0:
307 : : * @n_bytes: number of bytes to allocate
308 : : *
309 : : * Attempts to allocate @n_bytes, initialized to 0's, and returns %NULL on
310 : : * failure. Contrast with g_malloc0(), which aborts the program on failure.
311 : : *
312 : : * Since: 2.8
313 : : * Returns: the allocated memory, or %NULL
314 : : */
315 : : gpointer
316 : 7 : g_try_malloc0 (gsize n_bytes)
317 : : {
318 : : gpointer mem;
319 : :
320 [ + + ]: 7 : if (G_LIKELY (n_bytes))
321 : 2 : mem = calloc (1, n_bytes);
322 : : else
323 : 5 : mem = NULL;
324 : :
325 : 7 : return mem;
326 : : }
327 : :
328 : : /**
329 : : * g_try_realloc:
330 : : * @mem: (nullable): previously-allocated memory, or %NULL.
331 : : * @n_bytes: number of bytes to allocate.
332 : : *
333 : : * Attempts to realloc @mem to a new size, @n_bytes, and returns %NULL
334 : : * on failure. Contrast with g_realloc(), which aborts the program
335 : : * on failure.
336 : : *
337 : : * If @mem is %NULL, behaves the same as g_try_malloc().
338 : : *
339 : : * Returns: the allocated memory, or %NULL.
340 : : */
341 : : gpointer
342 : 41 : g_try_realloc (gpointer mem,
343 : : gsize n_bytes)
344 : : {
345 : : gpointer newmem;
346 : :
347 [ + + ]: 41 : if (G_LIKELY (n_bytes))
348 : 36 : newmem = realloc (mem, n_bytes);
349 : : else
350 : : {
351 : 5 : newmem = NULL;
352 : 5 : free (mem);
353 : : }
354 : :
355 : 41 : TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 1));
356 : :
357 : 41 : return newmem;
358 : : }
359 : :
360 : :
361 : : #define SIZE_OVERFLOWS(a,b) (G_UNLIKELY ((b) > 0 && (a) > G_MAXSIZE / (b)))
362 : :
363 : : /**
364 : : * g_malloc_n:
365 : : * @n_blocks: the number of blocks to allocate
366 : : * @n_block_bytes: the size of each block in bytes
367 : : *
368 : : * This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
369 : : * but care is taken to detect possible overflow during multiplication.
370 : : *
371 : : * If the allocation fails (because the system is out of memory),
372 : : * the program is terminated.
373 : : *
374 : : * Since: 2.24
375 : : * Returns: a pointer to the allocated memory
376 : : */
377 : : gpointer
378 : 20486702 : g_malloc_n (gsize n_blocks,
379 : : gsize n_block_bytes)
380 : : {
381 [ + - - + ]: 20486702 : if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
382 : : {
383 : 0 : g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
384 : : G_STRLOC, n_blocks, n_block_bytes);
385 : : }
386 : :
387 : 20486702 : return g_malloc (n_blocks * n_block_bytes);
388 : : }
389 : :
390 : : /**
391 : : * g_malloc0_n:
392 : : * @n_blocks: the number of blocks to allocate
393 : : * @n_block_bytes: the size of each block in bytes
394 : : *
395 : : * This function is similar to g_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes,
396 : : * but care is taken to detect possible overflow during multiplication.
397 : : *
398 : : * If the allocation fails (because the system is out of memory),
399 : : * the program is terminated.
400 : : *
401 : : * Since: 2.24
402 : : * Returns: a pointer to the allocated memory
403 : : */
404 : : gpointer
405 : 10027959 : g_malloc0_n (gsize n_blocks,
406 : : gsize n_block_bytes)
407 : : {
408 [ + - - + ]: 10027959 : if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
409 : : {
410 : 0 : g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
411 : : G_STRLOC, n_blocks, n_block_bytes);
412 : : }
413 : :
414 : 10027959 : return g_malloc0 (n_blocks * n_block_bytes);
415 : : }
416 : :
417 : : /**
418 : : * g_realloc_n:
419 : : * @mem: (nullable): the memory to reallocate
420 : : * @n_blocks: the number of blocks to allocate
421 : : * @n_block_bytes: the size of each block in bytes
422 : : *
423 : : * This function is similar to g_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
424 : : * but care is taken to detect possible overflow during multiplication.
425 : : *
426 : : * If the allocation fails (because the system is out of memory),
427 : : * the program is terminated.
428 : : *
429 : : * Since: 2.24
430 : : * Returns: the new address of the allocated memory
431 : : */
432 : : gpointer
433 : 508080 : g_realloc_n (gpointer mem,
434 : : gsize n_blocks,
435 : : gsize n_block_bytes)
436 : : {
437 [ + - - + ]: 508080 : if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
438 : : {
439 : 0 : g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
440 : : G_STRLOC, n_blocks, n_block_bytes);
441 : : }
442 : :
443 : 508080 : return g_realloc (mem, n_blocks * n_block_bytes);
444 : : }
445 : :
446 : : /**
447 : : * g_try_malloc_n:
448 : : * @n_blocks: the number of blocks to allocate
449 : : * @n_block_bytes: the size of each block in bytes
450 : : *
451 : : * This function is similar to g_try_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
452 : : * but care is taken to detect possible overflow during multiplication.
453 : : *
454 : : * Since: 2.24
455 : : * Returns: the allocated memory, or %NULL.
456 : : */
457 : : gpointer
458 : 386410 : g_try_malloc_n (gsize n_blocks,
459 : : gsize n_block_bytes)
460 : : {
461 [ + - + + ]: 386410 : if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
462 : 4 : return NULL;
463 : :
464 : 386406 : return g_try_malloc (n_blocks * n_block_bytes);
465 : : }
466 : :
467 : : /**
468 : : * g_try_malloc0_n:
469 : : * @n_blocks: the number of blocks to allocate
470 : : * @n_block_bytes: the size of each block in bytes
471 : : *
472 : : * This function is similar to g_try_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes,
473 : : * but care is taken to detect possible overflow during multiplication.
474 : : *
475 : : * Since: 2.24
476 : : * Returns: the allocated memory, or %NULL
477 : : */
478 : : gpointer
479 : 6 : g_try_malloc0_n (gsize n_blocks,
480 : : gsize n_block_bytes)
481 : : {
482 [ + - + + ]: 6 : if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
483 : 4 : return NULL;
484 : :
485 : 2 : return g_try_malloc0 (n_blocks * n_block_bytes);
486 : : }
487 : :
488 : : /**
489 : : * g_try_realloc_n:
490 : : * @mem: (nullable): previously-allocated memory, or %NULL.
491 : : * @n_blocks: the number of blocks to allocate
492 : : * @n_block_bytes: the size of each block in bytes
493 : : *
494 : : * This function is similar to g_try_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
495 : : * but care is taken to detect possible overflow during multiplication.
496 : : *
497 : : * Since: 2.24
498 : : * Returns: the allocated memory, or %NULL.
499 : : */
500 : : gpointer
501 : 6 : g_try_realloc_n (gpointer mem,
502 : : gsize n_blocks,
503 : : gsize n_block_bytes)
504 : : {
505 [ + - + + ]: 6 : if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
506 : 4 : return NULL;
507 : :
508 : 2 : return g_try_realloc (mem, n_blocks * n_block_bytes);
509 : : }
510 : :
511 : : /**
512 : : * g_mem_is_system_malloc:
513 : : *
514 : : * Checks whether the allocator used by g_malloc() is the system's
515 : : * malloc implementation. If it returns %TRUE memory allocated with
516 : : * malloc() can be used interchangeably with memory allocated using g_malloc().
517 : : * This function is useful for avoiding an extra copy of allocated memory returned
518 : : * by a non-GLib-based API.
519 : : *
520 : : * Returns: if %TRUE, malloc() and g_malloc() can be mixed.
521 : : *
522 : : * Deprecated: 2.46: GLib always uses the system malloc, so this function always
523 : : * returns %TRUE.
524 : : **/
525 : : gboolean
526 : 0 : g_mem_is_system_malloc (void)
527 : : {
528 : 0 : return TRUE;
529 : : }
530 : :
531 : : /**
532 : : * g_mem_set_vtable:
533 : : * @vtable: table of memory allocation routines.
534 : : *
535 : : * This function used to let you override the memory allocation function.
536 : : * However, its use was incompatible with the use of global constructors
537 : : * in GLib and GIO, because those use the GLib allocators before main is
538 : : * reached. Therefore this function is now deprecated and is just a stub.
539 : : *
540 : : * Deprecated: 2.46: This function now does nothing. Use other memory
541 : : * profiling tools instead
542 : : */
543 : : void
544 : 0 : g_mem_set_vtable (GMemVTable *vtable)
545 : : {
546 : 0 : g_warning (G_STRLOC ": custom memory allocation vtable not supported");
547 : 0 : }
548 : :
549 : :
550 : : /**
551 : : * glib_mem_profiler_table:
552 : : *
553 : : * Used to be a #GMemVTable containing profiling variants of the memory
554 : : * allocation functions, but this variable shouldn't be modified anymore.
555 : : *
556 : : * Deprecated: 2.46: Use other memory profiling tools instead
557 : : */
558 : : GMemVTable *glib_mem_profiler_table = &glib_mem_vtable;
559 : :
560 : : /**
561 : : * g_mem_profile:
562 : : *
563 : : * GLib used to support some tools for memory profiling, but this
564 : : * no longer works. There are many other useful tools for memory
565 : : * profiling these days which can be used instead.
566 : : *
567 : : * Deprecated: 2.46: Use other memory profiling tools instead
568 : : */
569 : : void
570 : 0 : g_mem_profile (void)
571 : : {
572 : 0 : g_warning (G_STRLOC ": memory profiling not supported");
573 : 0 : }
574 : :
575 : : /**
576 : : * g_aligned_alloc:
577 : : * @n_blocks: the number of blocks to allocate
578 : : * @n_block_bytes: the size of each block in bytes
579 : : * @alignment: the alignment to be enforced, which must be a positive power of 2
580 : : * and a multiple of `sizeof(void*)`
581 : : *
582 : : * This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes)
583 : : * bytes, but care is taken to align the allocated memory to with the given
584 : : * alignment value. Additionally, it will detect possible overflow during
585 : : * multiplication.
586 : : *
587 : : * If the allocation fails (because the system is out of memory),
588 : : * the program is terminated.
589 : : *
590 : : * Aligned memory allocations returned by this function can only be
591 : : * freed using g_aligned_free_sized() or g_aligned_free().
592 : : *
593 : : * Returns: (transfer full): the allocated memory
594 : : *
595 : : * Since: 2.72
596 : : */
597 : : gpointer
598 : 32 : g_aligned_alloc (gsize n_blocks,
599 : : gsize n_block_bytes,
600 : : gsize alignment)
601 : : {
602 : 32 : gpointer res = NULL;
603 : : gsize real_size;
604 : :
605 [ + - - + ]: 32 : if (G_UNLIKELY ((alignment == 0) || (alignment & (alignment - 1)) != 0))
606 : : {
607 : 0 : g_error ("%s: alignment %"G_GSIZE_FORMAT" must be a positive power of two",
608 : : G_STRLOC, alignment);
609 : : }
610 : :
611 [ - + ]: 32 : if (G_UNLIKELY ((alignment % sizeof (void *)) != 0))
612 : : {
613 : 0 : g_error ("%s: alignment %"G_GSIZE_FORMAT" must be a multiple of %"G_GSIZE_FORMAT,
614 : : G_STRLOC, alignment, sizeof (void *));
615 : : }
616 : :
617 [ + + - + ]: 32 : if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
618 : : {
619 : 0 : g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
620 : : G_STRLOC, n_blocks, n_block_bytes);
621 : : }
622 : :
623 : 32 : real_size = n_blocks * n_block_bytes;
624 : :
625 [ + + ]: 32 : if (G_UNLIKELY (real_size == 0))
626 : : {
627 : 15 : TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) real_size, 0, 0));
628 : 15 : return NULL;
629 : : }
630 : :
631 : : /* We need to clear errno because posix_memalign() will use its return
632 : : * value in the same way memalign() and aligned_alloc() will set errno.
633 : : * Additionally, posix_memalign() will warn if its return value is left
634 : : * unassigned.
635 : : *
636 : : * We handle all possible return values (ENOMEM and EINVAL) with either
637 : : * precondition or postcondition checking.
638 : : */
639 : 17 : errno = 0;
640 : :
641 : : #if defined(HAVE_POSIX_MEMALIGN)
642 : 17 : errno = posix_memalign (&res, alignment, real_size);
643 : : #elif defined(HAVE_ALIGNED_ALLOC) || defined(HAVE__ALIGNED_MALLOC)
644 : : /* real_size must be a multiple of alignment */
645 : : if (real_size % alignment != 0)
646 : : {
647 : : gsize offset = real_size % alignment;
648 : :
649 : : if (G_MAXSIZE - real_size < (alignment - offset))
650 : : {
651 : : g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"+%"G_GSIZE_FORMAT" bytes",
652 : : G_STRLOC, real_size, (alignment - offset));
653 : : }
654 : :
655 : : real_size += (alignment - offset);
656 : : }
657 : :
658 : : res = aligned_alloc (alignment, real_size);
659 : : #elif defined(HAVE_MEMALIGN)
660 : : res = memalign (alignment, real_size);
661 : : #else
662 : : # error "This platform does not have an aligned memory allocator."
663 : : #endif
664 : :
665 : 17 : TRACE (GLIB_MEM_ALLOC((void*) res, (unsigned int) real_size, 0, 0));
666 [ + - ]: 17 : if (res)
667 : 17 : return res;
668 : :
669 : 0 : g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
670 : : G_STRLOC, real_size);
671 : :
672 : : return NULL;
673 : : }
674 : :
675 : : /**
676 : : * g_aligned_alloc0:
677 : : * @n_blocks: the number of blocks to allocate
678 : : * @n_block_bytes: the size of each block in bytes
679 : : * @alignment: the alignment to be enforced, which must be a positive power of 2
680 : : * and a multiple of `sizeof(void*)`
681 : : *
682 : : * This function is similar to g_aligned_alloc(), but it will
683 : : * also clear the allocated memory before returning it.
684 : : *
685 : : * Returns: (transfer full): the allocated, cleared memory
686 : : *
687 : : * Since: 2.72
688 : : */
689 : : gpointer
690 : 11 : g_aligned_alloc0 (gsize n_blocks,
691 : : gsize n_block_bytes,
692 : : gsize alignment)
693 : : {
694 : 11 : gpointer res = g_aligned_alloc (n_blocks, n_block_bytes, alignment);
695 : :
696 [ + + ]: 11 : if (G_LIKELY (res != NULL))
697 : 6 : memset (res, 0, n_blocks * n_block_bytes);
698 : :
699 : 11 : return res;
700 : : }
701 : :
702 : : /**
703 : : * g_aligned_free:
704 : : * @mem: (nullable): the memory to deallocate
705 : : *
706 : : * Frees the memory allocated by g_aligned_alloc().
707 : : *
708 : : * Since: 2.72
709 : : */
710 : : void
711 : 12 : g_aligned_free (gpointer mem)
712 : : {
713 : 12 : aligned_free (mem);
714 : 12 : }
715 : :
716 : : /**
717 : : * g_aligned_free_sized:
718 : : * @mem: (nullable): the memory to free
719 : : * @alignment: alignment of @mem
720 : : * @size: size of @mem, in bytes
721 : : *
722 : : * Frees the memory pointed to by @mem, assuming it is has the given @size and
723 : : * @alignment.
724 : : *
725 : : * If @mem is %NULL this is a no-op (and @size is ignored).
726 : : *
727 : : * It is an error if @size doesn’t match the size, or @alignment doesn’t match
728 : : * the alignment, passed when @mem was allocated. @size and @alignment are
729 : : * passed to this function to allow optimizations in the allocator. If you
730 : : * don’t know either of them, use g_aligned_free() instead.
731 : : *
732 : : * Since: 2.76
733 : : */
734 : : void
735 : 10 : g_aligned_free_sized (void *mem,
736 : : size_t alignment,
737 : : size_t size)
738 : : {
739 : : #ifdef HAVE_FREE_ALIGNED_SIZED
740 : : free_aligned_sized (mem, alignment, size);
741 : : #else
742 : 10 : aligned_free (mem);
743 : : #endif
744 : 10 : }
|