Aligned Memory Blocks (The GNU C Library)

#### 3.2.3.7 Allocating Aligned Memory Blocks ¶

The address of a block returned by `malloc` or `realloc` in GNU systems is always a multiple of eight (or sixteen on 64-bit systems). If you need a block whose address is a multiple of a higher power of two than that, use `aligned_alloc` or `posix_memalign`. `aligned_alloc` and `posix_memalign` are declared in `stdlib.h`.

Function: `void *` aligned_alloc `(size_t alignment, size_t size)` ¶

  Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock fd mem | See POSIX Safety Concepts.

  The `aligned_alloc` function allocates a block of size bytes whose address is a multiple of alignment. The alignment must be a power of two.

  The `aligned_alloc` function returns a null pointer on error and sets `errno` to one of the following values:

  `ENOMEM`

    There was insufficient memory available to satisfy the request.

  `EINVAL`

    alignment is not a power of two.

    This function was introduced in ISO C11 and hence may have better portability to modern non-POSIX systems than `posix_memalign`.

Function: `void *` memalign `(size_t boundary, size_t size)` ¶

  Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock fd mem | See POSIX Safety Concepts.

  The `memalign` function allocates a block of size bytes whose address is a multiple of boundary. The boundary must be a power of two! The function `memalign` works by allocating a somewhat larger block, and then returning an address within the block that is on the specified boundary.

  The `memalign` function returns a null pointer on error and sets `errno` to one of the following values:

  `ENOMEM`

    There was insufficient memory available to satisfy the request.

  `EINVAL`

    boundary is not a power of two.

  The `memalign` function is obsolete and `aligned_alloc` or `posix_memalign` should be used instead.

Function: `int` posix_memalign `(void **memptr, size_t alignment, size_t size)` ¶

  Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock fd mem | See POSIX Safety Concepts.

  The `posix_memalign` function is similar to the `memalign` function in that it returns a buffer of size bytes aligned to a multiple of alignment. But it adds one requirement to the parameter alignment: the value must be a power of two multiple of `sizeof (void *)`.

  If the function succeeds in allocation memory a pointer to the allocated memory is returned in `*memptr` and the return value is zero. Otherwise the function returns an error value indicating the problem. The possible error values returned are:

  `ENOMEM`

    There was insufficient memory available to satisfy the request.

  `EINVAL`

    alignment is not a power of two multiple of `sizeof (void *)`.

  This function was introduced in POSIX 1003.1d. Although this function is superseded by `aligned_alloc`, it is more portable to older POSIX systems that do not support ISO C11.

Function: `void *` valloc `(size_t size)` ¶

  Preliminary: | MT-Unsafe init | AS-Unsafe init lock | AC-Unsafe init lock fd mem | See POSIX Safety Concepts.

  Using `valloc` is like using `memalign` and passing the page size as the value of the first argument. It is implemented like this:

      void *
      valloc (size_t size)
      {
        return memalign (getpagesize (), size);
      }

  How to get information about the memory subsystem? for more information about the memory subsystem.

  The `valloc` function is obsolete and `aligned_alloc` or `posix_memalign` should be used instead.

You can determine the alignment of a pointer with the `memalignment` function.

Function: `size_t` memalignment `(void *p)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This function, defined in C23, returns the alignment of p, as a power of two. If p is a null pointer, it returns zero. C23 requires p to be a valid pointer to an object or a null pointer; as a GNU extension, the GNU C Library supports this function on arbitrary bit patterns of pointer type.

  This function was added to the C23 standard to support unconventional platforms where a pointer’s low-order bits are unrelated to alignment. For conventional platforms, one can instead cast the pointer to `uintptr_t` and then test the low order bits: this is portable to pre-C23 and is typically a bit faster.

  For example, if you want to read an `int` addressed by possibly-misaligned pointer `p`, the following pre-C23 code works on all conventional platforms:

      int i;
      if (((uintptr_t) p & (alignof (int) - 1)) != 0)
        memcpy (&i, p, sizeof i);
      else
        i = *p;

  However, it might not work on unconventional platforms, where one would need something like the following C23 code:

      int i;
      if (memalignment (p) < alignof (int))
        memcpy (&i, p, sizeof i);
      else
        i = *p;

  However, for this particular case, performance does not improve if different code is used for aligned and unaligned pointers, and the following code is preferable:

      int i;
      memcpy (&i, p, sizeof i);

  The compiler will generate the most efficient way to access unaligned data for the architecture, optimizing away the `memcpy` call.