Сохраняет ли realloc выравнивание памяти в posix_memalign? - PullRequest
14 голосов
/ 31 января 2012

Выровнено malloc - это posix_memalign, это нормально, но как насчет выровненного realloc?Сохраняет ли realloc выравнивание или как гарантировать, что перераспределенная память имеет такое же выравнивание?Предположим, Linux и x86_64.

Ответы [ 3 ]

18 голосов
/ 31 января 2012

Нет, 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.

Но, как уже говорилось, документация не гарантирует этого.

1 голос
/ 31 января 2012

realloc ведет себя так же, как malloc, поэтому память, возвращаемая realloc, имеет то же ограничение выравнивания, что и malloc.

0 голосов
/ 31 января 2012

Если вы посмотрите на исходный код glibc для realloc, он напрямую вызывает malloc. Таким образом, память выровнена так же, как malloc.

...