Aligned malloc
is posix_memalign
, that's OK, but what about the aligned realloc
? Does realloc
retain the alignment or how to assure that reallocated memory has the same alignment? Assume Linux and x86_64.

- 347,512
- 102
- 1,199
- 985

- 23,584
- 43
- 124
- 195
-
2Nope - if you need a particular alignment e.g. for SIMD data, then don't use realloc. – Paul R Jan 31 '12 at 10:52
-
So, if I do need "aligned realloc", I must free and posix_memalign new memory, right? – Cartesius00 Jan 31 '12 at 10:54
-
1Yes - you could even implement your own `posix_memrealloc` like this if you really wanted to. – Paul R Jan 31 '12 at 10:55
-
"I must free and posix_memalign new memory, right?" - no, why not just implement the logic yourself: it's just a bit of padding, rounding and an offset - then you can call realloc.... Also, several of your questions are tagged C++ but really have nothing to do with C++. – Tony Delroy Jan 31 '12 at 10:56
-
@Tony: It's not that simple, "when padding" you waste memory, something like 1/2 at the worst case. – Cartesius00 Jan 31 '12 at 10:58
-
@Tony: you *could* call realloc, but if the new buffer is at a different alignment from the old one then you'd have to `memmove` everything and adjust your offset. – Steve Jessop Jan 31 '12 at 11:27
-
@James: true, but it's quite possible that posix_memalign implementations will be layered over malloc such that they're equally inefficient. Even if not, the real memory usage of such small allocations may be significantly more than the application-requested size given overheads for free lists etc., again effectively reducing the 1/2 figure. – Tony Delroy Feb 01 '12 at 00:41
-
@Steve: true, and could be a deal breaker depending on the performance needs. – Tony Delroy Feb 01 '12 at 00:41
2 Answers
No, realloc
on the memory returned from posix_memalign
is not guaranteed by either ISO or POSIX to maintain the same alignment. A realloc
may simply expand the current block at the same address but it may also move the block to a different address whose alignment is less strict than the original.
If you want the same alignment, it's probably best to allocate another block and copy the data over.
There is, unfortunately, no posix_memalign_realloc
function in the Single UNIX Specification either.
If you don't want to go through the hassle of copying data every time, you could try the realloc
(a) and, if the alignment of that was not as expected, then and only then call posix_memalign
to get a correctly aligned address and copy the data in to there, freeing the old address when done.
This may result in:
- zero copies (if the current block can be expanded in-place);
- one copy (if
realloc
copies but happens to give you a correctly aligned block); or - two copies (if
realloc
copies and then you also have to copy due to misalignment).
It may also result in less copying than indicated depending on the underlying memory management implementation. For example, a "copy" may simply involve remapping memory blocks rather than physically moving the data.
So you may want to keep some statistics to see if this scheme is worthwhile.
(a) Just keep in mind that neither POSIX nor Linux man pages specify whether or not you even can pass these pointers to realloc
, only that you can pass them to free
.
However, based on the current GNU libc source code, it appears to work, although that's no guarantee it will continue to work in future :-)
My fear was that it would allocate memory normally (standard alignment) and pass back an offset address (ie, not the actual address allocated, but one N
bytes beyond that) which free
was intelligent enough to turn back into the actual address before weaving its magic.
One way of doing that would be to store the actual address immediately before the returned address though this of course would lead to wastage even for regular allocations.
In that case, free
may have been made intelligent (since the specs say it must be able to handle the allocations done by posix_memalign
) but realloc
may not have been given the same intelligence (since the docs are silent on that matter).
However, based on GNU glibc 2.14.1, it actually allocates more memory than needed then fiddles with the arena to free up the pre-space and post-space, so that the address returned is a "real" address, usable by free
or realloc
.
But, as stated, the documentation doesn't guarantee this.
-
This answer is not correct in one important way: realloc usually does not copy even if the memory area moves. I think that if there isn't enough room at the current memory address to expand a buffer - the pages are remapped to avoid a copy. So its would be zero copies, zero copies, one copy. – Rafael Baptista May 05 '16 at 21:16
-
1@RafaelBaptista, you are confusing some *implementations* with the *standards.* There is *nothing* in the standards (ISO/POSIX) which mandates how things happen under the covers. However, it appears that the question was changed after my answer to assume Linux which narrows the field somewhat (but less than you may think since Linux runs on a huge variety of hardware with possibly wildly varying MMU options). Will adjust the answer to suit. – paxdiablo May 06 '16 at 02:22
If you look at the glibc source code for realloc, it calls directly on to malloc. So the memory is aligned in the same way as malloc.

- 141
- 5
-
Sorry, I should add. In the source, if there is additional heap space in the location already pointed to by the original malloc'd memory then it just allocates additional heap at the end of the original allocation size without calling malloc. This obviously won't change the alignment. – Carey Hickling Jan 31 '12 at 10:58
-
posix_memalign() is called in place of malloc; and makes guarantees that malloc doesn't. The question isn't about malloc + realloc, it is about posix_memalign and realloc. – mevets Aug 06 '19 at 18:47