Coverage Report

Created: 2026-10-14 08:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/glib-2.88.3/glib/gmem.c
Line
Count
Source
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
0
# 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
g_malloc (gsize n_bytes)
95
578k
{
96
578k
  if (G_LIKELY (n_bytes))
97
578k
    {
98
578k
      gpointer mem;
99
100
578k
      mem = malloc (n_bytes);
101
578k
      TRACE (GLIB_MEM_ALLOC ((void *) mem, n_bytes, 0, 0));
102
578k
      if (mem)
103
578k
  return mem;
104
105
578k
      g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
106
0
               G_STRLOC, n_bytes);
107
0
    }
108
109
10
  TRACE (GLIB_MEM_ALLOC ((void *) NULL, n_bytes, 0, 0));
110
111
10
  return NULL;
112
578k
}
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
g_malloc0 (gsize n_bytes)
128
217k
{
129
217k
  if (G_LIKELY (n_bytes))
130
217k
    {
131
217k
      gpointer mem;
132
133
217k
      mem = calloc (1, n_bytes);
134
217k
      TRACE (GLIB_MEM_ALLOC ((void *) mem, n_bytes, 1, 0));
135
217k
      if (mem)
136
217k
  return mem;
137
138
217k
      g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
139
0
               G_STRLOC, n_bytes);
140
0
    }
141
142
0
  TRACE (GLIB_MEM_ALLOC ((void *) NULL, n_bytes, 1, 0));
143
144
0
  return NULL;
145
217k
}
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
g_realloc (gpointer mem,
165
     gsize    n_bytes)
166
7.02k
{
167
7.02k
  gpointer newmem;
168
169
7.02k
  if (G_LIKELY (n_bytes))
170
7.02k
    {
171
7.02k
      newmem = realloc (mem, n_bytes);
172
7.02k
      TRACE (GLIB_MEM_REALLOC ((void *) newmem, (void *) mem, n_bytes, 0));
173
7.02k
      if (newmem)
174
7.02k
  return newmem;
175
176
7.02k
      g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
177
0
               G_STRLOC, n_bytes);
178
0
    }
179
180
0
  free (mem);
181
182
0
  TRACE (GLIB_MEM_REALLOC((void*) NULL, (void*)mem, 0, 0));
183
184
0
  return NULL;
185
7.02k
}
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
(g_free) (gpointer mem)
207
158M
{
208
158M
  free (mem);
209
158M
  TRACE(GLIB_MEM_FREE((void*) mem));
210
158M
}
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
g_free_sized (void   *mem,
233
              size_t  size)
234
298k
{
235
#ifdef HAVE_FREE_SIZED
236
  free_sized (mem, size);
237
#else
238
298k
  free (mem);
239
298k
#endif
240
298k
  TRACE (GLIB_MEM_FREE ((void*) mem));
241
298k
}
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 [callback@GLib.DestroyNotify] using the
261
 * standard calling convention for the platform that GLib was compiled for;
262
 * otherwise the program will experience undefined behaviour.
263
 *
264
 * Examples of this kind of undefined behaviour include using many Windows Win32
265
 * APIs, as well as many if not all OpenGL and Vulkan calls on 32-bit Windows,
266
 * which typically use the `__stdcall` calling convention rather than the
267
 * `__cdecl` calling convention.
268
 *
269
 * The affected functions can be used by wrapping them in a
270
 * [callback@GLib.DestroyNotify] that is declared with the standard calling
271
 * convention:
272
 *
273
 * ```c
274
 * // Wrapper needed to avoid mismatched calling conventions on Windows
275
 * static void
276
 * destroy_sync (void *sync)
277
 * {
278
 *   glDeleteSync (sync);
279
 * }
280
 *
281
 * // …
282
 *
283
 * g_clear_pointer (&sync, destroy_sync);
284
 * ```
285
286
 *
287
 * Since: 2.34
288
 **/
289
#undef g_clear_pointer
290
void
291
g_clear_pointer (gpointer      *pp,
292
                 GDestroyNotify destroy)
293
0
{
294
0
  gpointer _p;
295
296
0
  _p = *pp;
297
0
  if (_p)
298
0
    {
299
0
      *pp = NULL;
300
0
      destroy (_p);
301
0
    }
302
0
}
303
304
/**
305
 * g_try_malloc:
306
 * @n_bytes: number of bytes to allocate.
307
 * 
308
 * Attempts to allocate @n_bytes, and returns %NULL on failure.
309
 * Contrast with g_malloc(), which aborts the program on failure.
310
 * 
311
 * Returns: the allocated memory, or %NULL.
312
 */
313
gpointer
314
g_try_malloc (gsize n_bytes)
315
239k
{
316
239k
  gpointer mem;
317
318
239k
  if (G_LIKELY (n_bytes))
319
239k
    mem = malloc (n_bytes);
320
0
  else
321
0
    mem = NULL;
322
323
239k
  TRACE (GLIB_MEM_ALLOC ((void *) mem, n_bytes, 0, 1));
324
325
239k
  return mem;
326
239k
}
327
328
/**
329
 * g_try_malloc0:
330
 * @n_bytes: number of bytes to allocate
331
 * 
332
 * Attempts to allocate @n_bytes, initialized to 0's, and returns %NULL on
333
 * failure. Contrast with g_malloc0(), which aborts the program on failure.
334
 * 
335
 * Since: 2.8
336
 * Returns: the allocated memory, or %NULL
337
 */
338
gpointer
339
g_try_malloc0 (gsize n_bytes)
340
0
{
341
0
  gpointer mem;
342
343
0
  if (G_LIKELY (n_bytes))
344
0
    mem = calloc (1, n_bytes);
345
0
  else
346
0
    mem = NULL;
347
348
0
  return mem;
349
0
}
350
351
/**
352
 * g_try_realloc:
353
 * @mem: (nullable): previously-allocated memory, or %NULL.
354
 * @n_bytes: number of bytes to allocate.
355
 * 
356
 * Attempts to realloc @mem to a new size, @n_bytes, and returns %NULL
357
 * on failure. Contrast with g_realloc(), which aborts the program
358
 * on failure.
359
 *
360
 * If @mem is %NULL, behaves the same as g_try_malloc().
361
 * 
362
 * Returns: the allocated memory, or %NULL.
363
 */
364
gpointer
365
g_try_realloc (gpointer mem,
366
         gsize    n_bytes)
367
0
{
368
0
  gpointer newmem;
369
370
0
  if (G_LIKELY (n_bytes))
371
0
    newmem = realloc (mem, n_bytes);
372
0
  else
373
0
    {
374
0
      newmem = NULL;
375
0
      free (mem);
376
0
    }
377
378
0
  TRACE (GLIB_MEM_REALLOC ((void *) newmem, (void *) mem, n_bytes, 1));
379
380
0
  return newmem;
381
0
}
382
383
384
/**
385
 * g_malloc_n:
386
 * @n_blocks: the number of blocks to allocate
387
 * @n_block_bytes: the size of each block in bytes
388
 *
389
 * This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
390
 * but care is taken to detect possible overflow during multiplication.
391
 *
392
 * If the allocation fails (because the system is out of memory),
393
 * the program is terminated.
394
 *
395
 * Since: 2.24
396
 * Returns: a pointer to the allocated memory
397
 */
398
gpointer
399
g_malloc_n (gsize n_blocks,
400
      gsize n_block_bytes)
401
250k
{
402
250k
  size_t len;
403
404
250k
  if (!g_size_checked_mul (&len, n_blocks, n_block_bytes))
405
0
    {
406
0
      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
407
0
               G_STRLOC, n_blocks, n_block_bytes);
408
0
    }
409
410
250k
  return g_malloc (len);
411
250k
}
412
413
/**
414
 * g_malloc0_n:
415
 * @n_blocks: the number of blocks to allocate
416
 * @n_block_bytes: the size of each block in bytes
417
 *
418
 * This function is similar to g_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes,
419
 * but care is taken to detect possible overflow during multiplication.
420
 *
421
 * If the allocation fails (because the system is out of memory),
422
 * the program is terminated.
423
 *
424
 * Since: 2.24
425
 * Returns: a pointer to the allocated memory
426
 */
427
gpointer
428
g_malloc0_n (gsize n_blocks,
429
       gsize n_block_bytes)
430
179
{
431
179
  size_t len;
432
433
179
  if (!g_size_checked_mul (&len, n_blocks, n_block_bytes))
434
0
    {
435
0
      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
436
0
               G_STRLOC, n_blocks, n_block_bytes);
437
0
    }
438
439
179
  return g_malloc0 (len);
440
179
}
441
442
/**
443
 * g_realloc_n:
444
 * @mem: (nullable): the memory to reallocate
445
 * @n_blocks: the number of blocks to allocate
446
 * @n_block_bytes: the size of each block in bytes
447
 *
448
 * This function is similar to g_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
449
 * but care is taken to detect possible overflow during multiplication.
450
 *
451
 * If the allocation fails (because the system is out of memory),
452
 * the program is terminated.
453
 *
454
 * Since: 2.24
455
 * Returns: the new address of the allocated memory
456
 */
457
gpointer
458
g_realloc_n (gpointer mem,
459
       gsize    n_blocks,
460
       gsize    n_block_bytes)
461
1.25k
{
462
1.25k
  size_t len;
463
464
1.25k
  if (!g_size_checked_mul (&len, n_blocks, n_block_bytes))
465
0
    {
466
0
      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
467
0
               G_STRLOC, n_blocks, n_block_bytes);
468
0
    }
469
470
1.25k
  return g_realloc (mem, len);
471
1.25k
}
472
473
/**
474
 * g_try_malloc_n:
475
 * @n_blocks: the number of blocks to allocate
476
 * @n_block_bytes: the size of each block in bytes
477
 * 
478
 * This function is similar to g_try_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
479
 * but care is taken to detect possible overflow during multiplication.
480
 * 
481
 * Since: 2.24
482
 * Returns: the allocated memory, or %NULL.
483
 */
484
gpointer
485
g_try_malloc_n (gsize n_blocks,
486
    gsize n_block_bytes)
487
239k
{
488
239k
  size_t len;
489
490
239k
  if (!g_size_checked_mul (&len, n_blocks, n_block_bytes))
491
0
    return NULL;
492
493
239k
  return g_try_malloc (len);
494
239k
}
495
496
/**
497
 * g_try_malloc0_n:
498
 * @n_blocks: the number of blocks to allocate
499
 * @n_block_bytes: the size of each block in bytes
500
 * 
501
 * This function is similar to g_try_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes,
502
 * but care is taken to detect possible overflow during multiplication.
503
 * 
504
 * Since: 2.24
505
 * Returns: the allocated memory, or %NULL
506
 */
507
gpointer
508
g_try_malloc0_n (gsize n_blocks,
509
     gsize n_block_bytes)
510
0
{
511
0
  size_t len;
512
513
0
  if (!g_size_checked_mul (&len, n_blocks, n_block_bytes))
514
0
    return NULL;
515
516
0
  return g_try_malloc0 (len);
517
0
}
518
519
/**
520
 * g_try_realloc_n:
521
 * @mem: (nullable): previously-allocated memory, or %NULL.
522
 * @n_blocks: the number of blocks to allocate
523
 * @n_block_bytes: the size of each block in bytes
524
 * 
525
 * This function is similar to g_try_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
526
 * but care is taken to detect possible overflow during multiplication.
527
 * 
528
 * Since: 2.24
529
 * Returns: the allocated memory, or %NULL.
530
 */
531
gpointer
532
g_try_realloc_n (gpointer mem,
533
     gsize    n_blocks,
534
     gsize    n_block_bytes)
535
0
{
536
0
  size_t len;
537
538
0
  if (!g_size_checked_mul (&len, n_blocks, n_block_bytes))
539
0
    return NULL;
540
541
0
  return g_try_realloc (mem, len);
542
0
}
543
544
/**
545
 * g_mem_is_system_malloc:
546
 * 
547
 * Checks whether the allocator used by g_malloc() is the system's
548
 * malloc implementation. If it returns %TRUE memory allocated with
549
 * malloc() can be used interchangeably with memory allocated using g_malloc().
550
 * This function is useful for avoiding an extra copy of allocated memory returned
551
 * by a non-GLib-based API.
552
 *
553
 * Returns: if %TRUE, malloc() and g_malloc() can be mixed.
554
 *
555
 * Deprecated: 2.46: GLib always uses the system malloc, so this function always
556
 * returns %TRUE.
557
 **/
558
gboolean
559
g_mem_is_system_malloc (void)
560
0
{
561
0
  return TRUE;
562
0
}
563
564
/**
565
 * g_mem_set_vtable:
566
 * @vtable: table of memory allocation routines.
567
 * 
568
 * This function used to let you override the memory allocation function.
569
 * However, its use was incompatible with the use of global constructors
570
 * in GLib and GIO, because those use the GLib allocators before main is
571
 * reached. Therefore this function is now deprecated and is just a stub.
572
 *
573
 * Deprecated: 2.46: This function now does nothing. Use other memory
574
 * profiling tools instead
575
 */
576
void
577
g_mem_set_vtable (GMemVTable *vtable)
578
0
{
579
0
  g_warning (G_STRLOC ": custom memory allocation vtable not supported");
580
0
}
581
582
583
/**
584
 * glib_mem_profiler_table:
585
 *
586
 * Used to be a #GMemVTable containing profiling variants of the memory
587
 * allocation functions, but this variable shouldn't be modified anymore.
588
 *
589
 * Deprecated: 2.46: Use other memory profiling tools instead
590
 */
591
GMemVTable *glib_mem_profiler_table = &glib_mem_vtable;
592
593
/**
594
 * g_mem_profile:
595
 *
596
 * GLib used to support some tools for memory profiling, but this
597
 * no longer works. There are many other useful tools for memory
598
 * profiling these days which can be used instead.
599
 *
600
 * Deprecated: 2.46: Use other memory profiling tools instead
601
 */
602
void
603
g_mem_profile (void)
604
0
{
605
0
  g_warning (G_STRLOC ": memory profiling not supported");
606
0
}
607
608
/**
609
 * g_aligned_alloc:
610
 * @n_blocks: the number of blocks to allocate
611
 * @n_block_bytes: the size of each block in bytes
612
 * @alignment: the alignment to be enforced, which must be a positive power of 2
613
 *   and a multiple of `sizeof(void*)`
614
 *
615
 * This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes)
616
 * bytes, but care is taken to align the allocated memory to with the given
617
 * alignment value. Additionally, it will detect possible overflow during
618
 * multiplication.
619
 *
620
 * If the allocation fails (because the system is out of memory),
621
 * the program is terminated.
622
 *
623
 * Aligned memory allocations returned by this function can only be
624
 * freed using g_aligned_free_sized() or g_aligned_free().
625
 *
626
 * Returns: (transfer full): the allocated memory
627
 *
628
 * Since: 2.72
629
 */
630
gpointer
631
g_aligned_alloc (gsize n_blocks,
632
                 gsize n_block_bytes,
633
                 gsize alignment)
634
0
{
635
0
  gpointer res = NULL;
636
0
  gsize real_size;
637
638
0
  if (G_UNLIKELY ((alignment == 0) || (alignment & (alignment - 1)) != 0))
639
0
    {
640
0
      g_error ("%s: alignment %"G_GSIZE_FORMAT" must be a positive power of two",
641
0
               G_STRLOC, alignment);
642
0
    }
643
644
0
  if (G_UNLIKELY ((alignment % sizeof (void *)) != 0))
645
0
    {
646
0
      g_error ("%s: alignment %"G_GSIZE_FORMAT" must be a multiple of %"G_GSIZE_FORMAT,
647
0
               G_STRLOC, alignment, sizeof (void *));
648
0
    }
649
650
0
  if (!g_size_checked_mul (&real_size, n_blocks, n_block_bytes))
651
0
    {
652
0
      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
653
0
               G_STRLOC, n_blocks, n_block_bytes);
654
0
    }
655
656
0
  if (G_UNLIKELY (real_size == 0))
657
0
    {
658
0
      TRACE (GLIB_MEM_ALLOC ((void *) NULL, real_size, 0, 0));
659
0
      return NULL;
660
0
    }
661
662
  /* We need to clear errno because posix_memalign() will use its return
663
   * value in the same way memalign() and aligned_alloc() will set errno.
664
   * Additionally, posix_memalign() will warn if its return value is left
665
   * unassigned.
666
   *
667
   * We handle all possible return values (ENOMEM and EINVAL) with either
668
   * precondition or postcondition checking.
669
   */
670
0
  errno = 0;
671
672
0
#if defined(HAVE_POSIX_MEMALIGN)
673
0
  errno = posix_memalign (&res, alignment, real_size);
674
#elif defined(HAVE_ALIGNED_ALLOC) || defined(HAVE__ALIGNED_MALLOC)
675
  /* real_size must be a multiple of alignment */
676
  if (real_size % alignment != 0)
677
    {
678
      gsize offset = real_size % alignment;
679
680
      if (G_MAXSIZE - real_size < (alignment - offset))
681
        {
682
          g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"+%"G_GSIZE_FORMAT" bytes",
683
                   G_STRLOC, real_size, (alignment - offset));
684
        }
685
686
      real_size += (alignment - offset);
687
    }
688
689
  res = aligned_alloc (alignment, real_size);
690
#elif defined(HAVE_MEMALIGN)
691
  res = memalign (alignment, real_size);
692
#else
693
# error "This platform does not have an aligned memory allocator."
694
#endif
695
696
0
  TRACE (GLIB_MEM_ALLOC ((void *) res, real_size, 0, 0));
697
0
  if (res)
698
0
    return res;
699
700
0
  g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
701
0
           G_STRLOC, real_size);
702
703
0
  return NULL;
704
0
}
705
706
/**
707
 * g_aligned_alloc0:
708
 * @n_blocks: the number of blocks to allocate
709
 * @n_block_bytes: the size of each block in bytes
710
 * @alignment: the alignment to be enforced, which must be a positive power of 2
711
 *   and a multiple of `sizeof(void*)`
712
 *
713
 * This function is similar to g_aligned_alloc(), but it will
714
 * also clear the allocated memory before returning it.
715
 *
716
 * Returns: (transfer full): the allocated, cleared memory
717
 *
718
 * Since: 2.72
719
 */
720
gpointer
721
g_aligned_alloc0 (gsize n_blocks,
722
                  gsize n_block_bytes,
723
                  gsize alignment)
724
0
{
725
0
  gpointer res = g_aligned_alloc (n_blocks, n_block_bytes, alignment);
726
727
0
  if (G_LIKELY (res != NULL))
728
0
    memset (res, 0, n_blocks * n_block_bytes);
729
730
0
  return res;
731
0
}
732
733
/**
734
 * g_aligned_free:
735
 * @mem: (nullable): the memory to deallocate
736
 *
737
 * Frees the memory allocated by g_aligned_alloc().
738
 *
739
 * Since: 2.72
740
 */
741
void
742
g_aligned_free (gpointer mem)
743
0
{
744
0
  aligned_free (mem);
745
0
}
746
747
/**
748
 * g_aligned_free_sized:
749
 * @mem: (nullable): the memory to free
750
 * @alignment: alignment of @mem
751
 * @size: size of @mem, in bytes
752
 *
753
 * Frees the memory pointed to by @mem, assuming it is has the given @size and
754
 * @alignment.
755
 *
756
 * If @mem is %NULL this is a no-op (and @size is ignored).
757
 *
758
 * It is an error if @size doesn’t match the size, or @alignment doesn’t match
759
 * the alignment, passed when @mem was allocated. @size and @alignment are
760
 * passed to this function to allow optimizations in the allocator. If you
761
 * don’t know either of them, use g_aligned_free() instead.
762
 *
763
 * Since: 2.76
764
 */
765
void
766
g_aligned_free_sized (void   *mem,
767
                      size_t  alignment,
768
                      size_t  size)
769
0
{
770
#ifdef HAVE_FREE_ALIGNED_SIZED
771
  free_aligned_sized (mem, alignment, size);
772
#else
773
0
  aligned_free (mem);
774
0
#endif
775
0
}