Coverage Report

Created: 2026-05-16 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/glib/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
1.84M
{
96
1.84M
  if (G_LIKELY (n_bytes))
97
1.84M
    {
98
1.84M
      gpointer mem;
99
100
1.84M
      mem = malloc (n_bytes);
101
1.84M
      TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 0));
102
1.84M
      if (mem)
103
1.84M
  return mem;
104
105
1.84M
      g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
106
0
               G_STRLOC, n_bytes);
107
0
    }
108
109
0
  TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 0, 0));
110
111
0
  return NULL;
112
1.84M
}
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
1.56M
{
129
1.56M
  if (G_LIKELY (n_bytes))
130
1.56M
    {
131
1.56M
      gpointer mem;
132
133
1.56M
      mem = calloc (1, n_bytes);
134
1.56M
      TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 1, 0));
135
1.56M
      if (mem)
136
1.56M
  return mem;
137
138
1.56M
      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, (int) n_bytes, 1, 0));
143
144
0
  return NULL;
145
1.56M
}
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
447k
{
167
447k
  gpointer newmem;
168
169
447k
  if (G_LIKELY (n_bytes))
170
447k
    {
171
447k
      newmem = realloc (mem, n_bytes);
172
447k
      TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 0));
173
447k
      if (newmem)
174
447k
  return newmem;
175
176
447k
      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
447k
}
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
1.96M
{
208
1.96M
  free (mem);
209
1.96M
  TRACE(GLIB_MEM_FREE((void*) mem));
210
1.96M
}
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
883k
{
235
#ifdef HAVE_FREE_SIZED
236
  free_sized (mem, size);
237
#else
238
883k
  free (mem);
239
883k
#endif
240
883k
  TRACE (GLIB_MEM_FREE ((void*) mem));
241
883k
}
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
89.1k
{
316
89.1k
  gpointer mem;
317
318
89.1k
  if (G_LIKELY (n_bytes))
319
89.1k
    mem = malloc (n_bytes);
320
0
  else
321
0
    mem = NULL;
322
323
89.1k
  TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 1));
324
325
89.1k
  return mem;
326
89.1k
}
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
29.2k
{
341
29.2k
  gpointer mem;
342
343
29.2k
  if (G_LIKELY (n_bytes))
344
29.2k
    mem = calloc (1, n_bytes);
345
0
  else
346
0
    mem = NULL;
347
348
29.2k
  return mem;
349
29.2k
}
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
2.75k
{
368
2.75k
  gpointer newmem;
369
370
2.75k
  if (G_LIKELY (n_bytes))
371
2.75k
    newmem = realloc (mem, n_bytes);
372
0
  else
373
0
    {
374
0
      newmem = NULL;
375
0
      free (mem);
376
0
    }
377
378
2.75k
  TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 1));
379
380
2.75k
  return newmem;
381
2.75k
}
382
383
384
95.2k
#define SIZE_OVERFLOWS(a,b) (G_UNLIKELY ((b) > 0 && (a) > G_MAXSIZE / (b)))
385
386
/**
387
 * g_malloc_n:
388
 * @n_blocks: the number of blocks to allocate
389
 * @n_block_bytes: the size of each block in bytes
390
 *
391
 * This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
392
 * but care is taken to detect possible overflow during multiplication.
393
 *
394
 * If the allocation fails (because the system is out of memory),
395
 * the program is terminated.
396
 *
397
 * Since: 2.24
398
 * Returns: a pointer to the allocated memory
399
 */
400
gpointer
401
g_malloc_n (gsize n_blocks,
402
      gsize n_block_bytes)
403
30.2k
{
404
30.2k
  if (SIZE_OVERFLOWS (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
30.2k
  return g_malloc (n_blocks * n_block_bytes);
411
30.2k
}
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
838
{
431
838
  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
432
0
    {
433
0
      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
434
0
               G_STRLOC, n_blocks, n_block_bytes);
435
0
    }
436
437
838
  return g_malloc0 (n_blocks * n_block_bytes);
438
838
}
439
440
/**
441
 * g_realloc_n:
442
 * @mem: (nullable): the memory to reallocate
443
 * @n_blocks: the number of blocks to allocate
444
 * @n_block_bytes: the size of each block in bytes
445
 *
446
 * This function is similar to g_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
447
 * but care is taken to detect possible overflow during multiplication.
448
 *
449
 * If the allocation fails (because the system is out of memory),
450
 * the program is terminated.
451
 *
452
 * Since: 2.24
453
 * Returns: the new address of the allocated memory
454
 */
455
gpointer
456
g_realloc_n (gpointer mem,
457
       gsize    n_blocks,
458
       gsize    n_block_bytes)
459
9.28k
{
460
9.28k
  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
461
0
    {
462
0
      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
463
0
               G_STRLOC, n_blocks, n_block_bytes);
464
0
    }
465
466
9.28k
  return g_realloc (mem, n_blocks * n_block_bytes);
467
9.28k
}
468
469
/**
470
 * g_try_malloc_n:
471
 * @n_blocks: the number of blocks to allocate
472
 * @n_block_bytes: the size of each block in bytes
473
 * 
474
 * This function is similar to g_try_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
475
 * but care is taken to detect possible overflow during multiplication.
476
 * 
477
 * Since: 2.24
478
 * Returns: the allocated memory, or %NULL.
479
 */
480
gpointer
481
g_try_malloc_n (gsize n_blocks,
482
    gsize n_block_bytes)
483
26.1k
{
484
26.1k
  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
485
0
    return NULL;
486
487
26.1k
  return g_try_malloc (n_blocks * n_block_bytes);
488
26.1k
}
489
490
/**
491
 * g_try_malloc0_n:
492
 * @n_blocks: the number of blocks to allocate
493
 * @n_block_bytes: the size of each block in bytes
494
 * 
495
 * This function is similar to g_try_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes,
496
 * but care is taken to detect possible overflow during multiplication.
497
 * 
498
 * Since: 2.24
499
 * Returns: the allocated memory, or %NULL
500
 */
501
gpointer
502
g_try_malloc0_n (gsize n_blocks,
503
     gsize n_block_bytes)
504
28.7k
{
505
28.7k
  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
506
0
    return NULL;
507
508
28.7k
  return g_try_malloc0 (n_blocks * n_block_bytes);
509
28.7k
}
510
511
/**
512
 * g_try_realloc_n:
513
 * @mem: (nullable): previously-allocated memory, or %NULL.
514
 * @n_blocks: the number of blocks to allocate
515
 * @n_block_bytes: the size of each block in bytes
516
 * 
517
 * This function is similar to g_try_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
518
 * but care is taken to detect possible overflow during multiplication.
519
 * 
520
 * Since: 2.24
521
 * Returns: the allocated memory, or %NULL.
522
 */
523
gpointer
524
g_try_realloc_n (gpointer mem,
525
     gsize    n_blocks,
526
     gsize    n_block_bytes)
527
0
{
528
0
  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
529
0
    return NULL;
530
531
0
  return g_try_realloc (mem, n_blocks * n_block_bytes);
532
0
}
533
534
/**
535
 * g_mem_is_system_malloc:
536
 * 
537
 * Checks whether the allocator used by g_malloc() is the system's
538
 * malloc implementation. If it returns %TRUE memory allocated with
539
 * malloc() can be used interchangeably with memory allocated using g_malloc().
540
 * This function is useful for avoiding an extra copy of allocated memory returned
541
 * by a non-GLib-based API.
542
 *
543
 * Returns: if %TRUE, malloc() and g_malloc() can be mixed.
544
 *
545
 * Deprecated: 2.46: GLib always uses the system malloc, so this function always
546
 * returns %TRUE.
547
 **/
548
gboolean
549
g_mem_is_system_malloc (void)
550
0
{
551
0
  return TRUE;
552
0
}
553
554
/**
555
 * g_mem_set_vtable:
556
 * @vtable: table of memory allocation routines.
557
 * 
558
 * This function used to let you override the memory allocation function.
559
 * However, its use was incompatible with the use of global constructors
560
 * in GLib and GIO, because those use the GLib allocators before main is
561
 * reached. Therefore this function is now deprecated and is just a stub.
562
 *
563
 * Deprecated: 2.46: This function now does nothing. Use other memory
564
 * profiling tools instead
565
 */
566
void
567
g_mem_set_vtable (GMemVTable *vtable)
568
0
{
569
0
  g_warning (G_STRLOC ": custom memory allocation vtable not supported");
570
0
}
571
572
573
/**
574
 * glib_mem_profiler_table:
575
 *
576
 * Used to be a #GMemVTable containing profiling variants of the memory
577
 * allocation functions, but this variable shouldn't be modified anymore.
578
 *
579
 * Deprecated: 2.46: Use other memory profiling tools instead
580
 */
581
GMemVTable *glib_mem_profiler_table = &glib_mem_vtable;
582
583
/**
584
 * g_mem_profile:
585
 *
586
 * GLib used to support some tools for memory profiling, but this
587
 * no longer works. There are many other useful tools for memory
588
 * profiling these days which can be used instead.
589
 *
590
 * Deprecated: 2.46: Use other memory profiling tools instead
591
 */
592
void
593
g_mem_profile (void)
594
0
{
595
0
  g_warning (G_STRLOC ": memory profiling not supported");
596
0
}
597
598
/**
599
 * g_aligned_alloc:
600
 * @n_blocks: the number of blocks to allocate
601
 * @n_block_bytes: the size of each block in bytes
602
 * @alignment: the alignment to be enforced, which must be a positive power of 2
603
 *   and a multiple of `sizeof(void*)`
604
 *
605
 * This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes)
606
 * bytes, but care is taken to align the allocated memory to with the given
607
 * alignment value. Additionally, it will detect possible overflow during
608
 * multiplication.
609
 *
610
 * If the allocation fails (because the system is out of memory),
611
 * the program is terminated.
612
 *
613
 * Aligned memory allocations returned by this function can only be
614
 * freed using g_aligned_free_sized() or g_aligned_free().
615
 *
616
 * Returns: (transfer full): the allocated memory
617
 *
618
 * Since: 2.72
619
 */
620
gpointer
621
g_aligned_alloc (gsize n_blocks,
622
                 gsize n_block_bytes,
623
                 gsize alignment)
624
0
{
625
0
  gpointer res = NULL;
626
0
  gsize real_size;
627
628
0
  if (G_UNLIKELY ((alignment == 0) || (alignment & (alignment - 1)) != 0))
629
0
    {
630
0
      g_error ("%s: alignment %"G_GSIZE_FORMAT" must be a positive power of two",
631
0
               G_STRLOC, alignment);
632
0
    }
633
634
0
  if (G_UNLIKELY ((alignment % sizeof (void *)) != 0))
635
0
    {
636
0
      g_error ("%s: alignment %"G_GSIZE_FORMAT" must be a multiple of %"G_GSIZE_FORMAT,
637
0
               G_STRLOC, alignment, sizeof (void *));
638
0
    }
639
640
0
  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
641
0
    {
642
0
      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
643
0
               G_STRLOC, n_blocks, n_block_bytes);
644
0
    }
645
646
0
  real_size = n_blocks * n_block_bytes;
647
648
0
  if (G_UNLIKELY (real_size == 0))
649
0
    {
650
0
      TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) real_size, 0, 0));
651
0
      return NULL;
652
0
    }
653
654
  /* We need to clear errno because posix_memalign() will use its return
655
   * value in the same way memalign() and aligned_alloc() will set errno.
656
   * Additionally, posix_memalign() will warn if its return value is left
657
   * unassigned.
658
   *
659
   * We handle all possible return values (ENOMEM and EINVAL) with either
660
   * precondition or postcondition checking.
661
   */
662
0
  errno = 0;
663
664
0
#if defined(HAVE_POSIX_MEMALIGN)
665
0
  errno = posix_memalign (&res, alignment, real_size);
666
#elif defined(HAVE_ALIGNED_ALLOC) || defined(HAVE__ALIGNED_MALLOC)
667
  /* real_size must be a multiple of alignment */
668
  if (real_size % alignment != 0)
669
    {
670
      gsize offset = real_size % alignment;
671
672
      if (G_MAXSIZE - real_size < (alignment - offset))
673
        {
674
          g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"+%"G_GSIZE_FORMAT" bytes",
675
                   G_STRLOC, real_size, (alignment - offset));
676
        }
677
678
      real_size += (alignment - offset);
679
    }
680
681
  res = aligned_alloc (alignment, real_size);
682
#elif defined(HAVE_MEMALIGN)
683
  res = memalign (alignment, real_size);
684
#else
685
# error "This platform does not have an aligned memory allocator."
686
#endif
687
688
0
  TRACE (GLIB_MEM_ALLOC((void*) res, (unsigned int) real_size, 0, 0));
689
0
  if (res)
690
0
    return res;
691
692
0
  g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
693
0
           G_STRLOC, real_size);
694
695
0
  return NULL;
696
0
}
697
698
/**
699
 * g_aligned_alloc0:
700
 * @n_blocks: the number of blocks to allocate
701
 * @n_block_bytes: the size of each block in bytes
702
 * @alignment: the alignment to be enforced, which must be a positive power of 2
703
 *   and a multiple of `sizeof(void*)`
704
 *
705
 * This function is similar to g_aligned_alloc(), but it will
706
 * also clear the allocated memory before returning it.
707
 *
708
 * Returns: (transfer full): the allocated, cleared memory
709
 *
710
 * Since: 2.72
711
 */
712
gpointer
713
g_aligned_alloc0 (gsize n_blocks,
714
                  gsize n_block_bytes,
715
                  gsize alignment)
716
0
{
717
0
  gpointer res = g_aligned_alloc (n_blocks, n_block_bytes, alignment);
718
719
0
  if (G_LIKELY (res != NULL))
720
0
    memset (res, 0, n_blocks * n_block_bytes);
721
722
0
  return res;
723
0
}
724
725
/**
726
 * g_aligned_free:
727
 * @mem: (nullable): the memory to deallocate
728
 *
729
 * Frees the memory allocated by g_aligned_alloc().
730
 *
731
 * Since: 2.72
732
 */
733
void
734
g_aligned_free (gpointer mem)
735
0
{
736
0
  aligned_free (mem);
737
0
}
738
739
/**
740
 * g_aligned_free_sized:
741
 * @mem: (nullable): the memory to free
742
 * @alignment: alignment of @mem
743
 * @size: size of @mem, in bytes
744
 *
745
 * Frees the memory pointed to by @mem, assuming it is has the given @size and
746
 * @alignment.
747
 *
748
 * If @mem is %NULL this is a no-op (and @size is ignored).
749
 *
750
 * It is an error if @size doesn’t match the size, or @alignment doesn’t match
751
 * the alignment, passed when @mem was allocated. @size and @alignment are
752
 * passed to this function to allow optimizations in the allocator. If you
753
 * don’t know either of them, use g_aligned_free() instead.
754
 *
755
 * Since: 2.76
756
 */
757
void
758
g_aligned_free_sized (void   *mem,
759
                      size_t  alignment,
760
                      size_t  size)
761
0
{
762
#ifdef HAVE_FREE_ALIGNED_SIZED
763
  free_aligned_sized (mem, alignment, size);
764
#else
765
0
  aligned_free (mem);
766
0
#endif
767
0
}