std::aligned_alloc(3)

NAME
std::aligned_alloc - std::aligned_alloc

Synopsis
   Defined in header <cstdlib>
   void* aligned_alloc( std::size_t alignment, std::size_t size ); (since C++17)
   Allocate size bytes of uninitialized storage whose alignment is specified by
   alignment. The size parameter must be an integral multiple of alignment.
   The following functions are required to be thread-safe:
     * The library versions of operator new and operator delete
     * User replacement versions of global operator new and operator
       delete
     * std::calloc, std::malloc, std::realloc, (since C++11)
       std::aligned_alloc
       (since C++17), std::free
   Calls to these functions that allocate or deallocate a particular unit
   of storage occur in a single total order, and each such deallocation
   call happens-before the next allocation (if any) in this order.

Parameters
   alignment - specifies the alignment. Must be a valid alignment supported by the
               implementation.
   size - number of bytes to allocate. An integral multiple of alignment

Return value
   On success, returns the pointer to the beginning of newly allocated memory. To avoid
   a memory leak, the returned pointer must be deallocated with std::free() or
   std::realloc().
   On failure, returns a null pointer.

Notes
   Passing a size which is not an integral multiple of alignment or an alignment which
   is not valid or not supported by the implementation causes the function to fail and
   return a null pointer (C11, as published, specified undefined behavior in this case,
   this was corrected by DR 460).
   As an example of the "supported by the implementation" requirement, POSIX function
   posix_memalign accepts any alignment that is a power of two and a multiple of
   sizeof(void*), and POSIX-based implementations of aligned_alloc inherit this
   requirements.
   Regular std::malloc aligns memory suitable for any object type (which, in practice,
   means that it is aligned to alignof(std::max_align_t)). This function is useful for
   over-aligned allocations, such as to SSE, cache line, or VM page boundary.

Example
// Run this code
 #include <cstdio>
 #include <cstdlib>
 int main()
 {
     int* p1 = static_cast<int*>(std::malloc(10*sizeof *p1));
     std::printf("default-aligned address: %p\n", static_cast<void*>(p1));
     std::free(p1);
     int* p2 = static_cast<int*>(std::aligned_alloc(1024, 1024));
     std::printf("1024-byte aligned address: %p\n", static_cast<void*>(p2));
     std::free(p2);
 }

Possible output:
 default-aligned address: 0x2221c20
 1024-byte aligned address: 0x2222400

See also
   aligned_storage defines the type suitable for use as uninitialized
   (C++11)(deprecated in C++23) storage for types of given size
                        (class template)