问题
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,
- Why?
- What can be used instead on those platforms? Is there nothing better than calling
aligned_alloc
with the new alignment, and then doingmemcpy
andfree
ing the old pointer on success?
回答1:
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!
回答2:
Intel Math Kernel Library (free; available for Windows, Linux and macOS) ver. >= 11.3.1 has mkl_realloc
that preserves alignment:
Simple example:
auto p1 = std::aligned_alloc(1024, 1000);
std::cout << reinterpret_cast<std::uintptr_t>(p1) % 1024 << std::endl;
auto p2 = std::realloc(p1, 2000);
std::cout << reinterpret_cast<std::uintptr_t>(p2) % 1024 << std::endl;
auto p3 = std::realloc(p2, 3000);
std::cout << reinterpret_cast<std::uintptr_t>(p3) % 1024 << std::endl;
auto q1 = mkl_malloc(1000, 1024);
std::cout << reinterpret_cast<std::uintptr_t>(q1) % 1024 << std::endl;
auto q2 = mkl_realloc(q1, 2000);
std::cout << reinterpret_cast<std::uintptr_t>(q2) % 1024 << std::endl;
auto q3 = mkl_realloc(q2, 3000);
std::cout << reinterpret_cast<std::uintptr_t>(q3) % 1024 << std::endl;
The output on my machine is:
0
784
784
0
0
0
来源:https://stackoverflow.com/questions/56619623/why-is-there-no-aligned-realloc-on-most-platforms