Нет, realloc
в памяти, возвращенной из posix_memalign
, не гарантируется ни ISO, ни POSIX для сохранения того же выравнивания. A realloc
может просто развернуть текущий блок по тому же адресу, но может также переместить блок на другой адрес, выравнивание которого менее строго, чем оригинал.
Если вам нужно такое же выравнивание, вероятно, лучше выделить другой блок и скопировать данные поверх.
К сожалению, в спецификации Single UNIX также нет функции posix_memalign_realloc
.
Если вы не хотите проходить через копирование данных каждый раз, вы можете попробовать realloc
(a) и, если выравнивание этого было не так, как ожидалось, тогда и только тогда вызовите posix_memalign
, чтобы получить правильно выровненный адрес и скопировать туда данные, освободив старый адрес, когда закончите.
Это может привести к:
- ноль копий (если текущий блок можно развернуть на месте);
- одна копия (если
realloc
копирует, но получается правильно выровненный блок); или
- две копии (если
realloc
копии, а затем вам также придется копировать из-за смещения).
Это может также привести к меньшему количеству копирования, чем указано в зависимости от базовой реализации управления памятью. Например, «копирование» может просто включать переназначение блоков памяти, а не физическое перемещение данных.
Так что вы можете захотеть сохранить некоторую статистику, чтобы увидеть, стоит ли эта схема.
(a) Просто имейте в виду, что ни в справочных страницах POSIX, ни в Linux не указано, можете ли вы передавать эти указатели на realloc
, только чтобы вы могли их передавать до free
.
Однако, основываясь на текущем исходном коде libc GNU, он, кажется, работает, хотя это не гарантирует, что он продолжит работать в будущем: -)
Я боялся, что он выделит память нормально (стандартное выравнивание) и передаст обратно смещенный адрес (т. Е. Не выделенный адрес actaul, а один N
байт), который free
был достаточно умен, чтобы вернуться назад. на фактический адрес, прежде чем соткать его магию.
Один из способов сделать это - сохранить фактический адрес непосредственно перед возвращенным адресом, хотя это, конечно, приведет к потере даже при регулярных распределениях.
В этом случае free
может быть сделано интеллектуальным (так как спецификации говорят, что он должен быть в состоянии обработать распределения, выполненные posix_memalign
), но realloc
, возможно, не был предоставлен тот же интеллект (так как документы молчим по этому вопросу).
Однако, основываясь на GNU glibc 2.14.1, он на самом деле выделяет больше памяти, чем необходимо, чем возится с ареной, чтобы освободить пространство до и после пространства, так что возвращаемый адрес является «реальным» адресом, пригодным для использования free
или realloc
.
Но, как уже говорилось, документация не гарантирует этого.