Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no 'aligned_realloc' on most platforms?

MSVC has its own non-standard functions _aligned_malloc, _aligned_realloc and _aligned_free.

C++17 and C11 have introduced (std::)aligned_alloc, results of which can be deallocated with free or realloc. But realloc cannot be used to actually reallocate memory returned by aligned_alloc, since it does not take an alignment parameter and thus cannot guarantee that the returned pointer will be properly aligned.

I can't even find any non-standard extensions that could reallocate aligned memory (preserving its alignment) on platforms other than Microsoft Windows / Visual C++.

Am I searching for it wrong, or is there indeed no _aligned_realloc alternative on POSIX and other platforms?

If so,

  1. Why?
  2. What can be used instead on those platforms? Is there nothing better than calling aligned_alloc with the new alignment, and then doing memcpy and freeing the old pointer on success?
like image 581
Taras Avatar asked Jun 16 '19 14:06

Taras


People also ask

What is Posix_memalign?

The function posix_memalign() allocates size bytes and places the address of the allocated memory in *memptr. The address of the allocated memory will be a multiple of alignment, which must be a power of two and a multiple of sizeof(void *). This address can later be successfully passed to free(3).

Is malloc 16 byte aligned?

The GNU documentation states that malloc is aligned to 16 byte multiples on 64 bit systems.

What is the alignment of malloc?

new and malloc, by default, align address to 8 bytes (x86) or 16 bytes (x64), which is the optimal for most complex data.

Does malloc allocate aligned memory?

The malloc function allocates a memory block of at least size bytes. The block may be larger than size bytes because of the space that's required for alignment and maintenance information. malloc sets errno to ENOMEM if a memory allocation fails or if the amount of memory requested exceeds _HEAP_MAXREQ .


1 Answers

While POSIX (which tends to act as a lowest common denominator on most platforms) does not have an aligned_realloc, it does have aligned_alloc and memcpy. Therefore you can very easily implement your own aligned_realloc which is guaranteed to work on any reasonably posix compliant platform using these. However, note that there is not a posix standard method to get the size of a malloc'd region of memory. You'll have to track that yourself.

EDIT: have a bit of free time so I'm extending this to answer the most common criticism

What I've proposed is, as the astute commenter will note, not how realloc works internally.

Under the hood, your standard realloc implementation will do its damnedest to avoid preforming the above behavior of mallocing and memcpying with a free afterwards. It will try to use one of two behaviors before resorting to the fallback. 1) If the new size is smaller than the old size, it will resize the memory in place, avoiding having to allocate, copy, or free. 2) if the new size is greater than the old size, it will (in simplified terms) see if there is free memory of sufficient size adjacent, and if so it will gobble up that memory and resize in place. If not, it resorts to the fallback.

I proposed a naive approach, because I figured most people asking this question wouldn't want to have to implement their own malloc implementation. (Though I highly suggest doing such for educational purposes)

Hope this satisfies any complaints!

like image 163
Valyrie H. Autumn Avatar answered Nov 24 '22 08:11

Valyrie H. Autumn