Подтвердить что ты не робот

Поддерживает ли realloc выравнивание памяти posix_memalign?

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

4b9b3361

Ответ 1

Нет, realloc в памяти, возвращенной из posix_memalign, не гарантируется ни ISO, ни POSIX для поддержания того же выравнивания. A realloc может просто расширить текущий блок по тому же адресу, но он также может переместить блок на другой адрес, выравнивание которого будет менее строгим, чем оригинал.

Если вам нужно такое же выравнивание, лучше всего выделить другой блок и скопировать данные.

В спецификации Single UNIX есть, к сожалению, функция posix_memalign_realloc.

Если вы не хотите каждый раз перебирать данные копирования, вы можете попробовать realloc (a) и если выравнивание этого не было таким, как ожидалось, тогда и только затем вызовите posix_memalign, чтобы получить правильно выровненный адрес и скопировать данные туда, освободив старый адрес, когда закончите.

Это может привести к:

  • нулевые копии (если текущий блок можно развернуть на месте);
  • одна копия (если realloc копии, но, случается, дает вам правильно выровненный блок); или
  • две копии (если realloc копии, а затем вы также должны скопировать из-за несоосности).

Это может также привести к меньшему копированию, чем указано, в зависимости от реализации управления базой данных. Например, "копия" может просто включать переназначение блоков памяти, а не физическое перемещение данных.

Таким образом, вы можете захотеть сохранить некоторую статистику, чтобы увидеть, стоит ли эта схема.


(a) Просто имейте в виду, что ни страницы руководства POSIX, ни Linux не указывают, можете ли вы даже передать эти указатели на realloc, только чтобы передать их в free.

Однако, основываясь на текущем исходном коде GNU libc, он работает, хотя и не гарантирует, что он будет продолжать работать в будущем: -)

Я опасался, что он будет нормально распределять память (стандартное выравнивание) и передавать обратно адрес смещения (т.е. не выделенный адрес actaul, а один N байты за ним), который free был достаточно интеллектуальным, чтобы повернуть назад в фактический адрес, прежде чем соткать его магию.

Один из способов сделать это - сохранить фактический адрес непосредственно перед возвращенным адресом, хотя это, конечно, приведет к отпуску даже для регулярных распределений.

В этом случае free, возможно, был сделан интеллектуальным (поскольку спецификации говорят, что он должен иметь возможность обрабатывать распределения, выполняемые posix_memalign), но realloc, возможно, не получил такой же интеллект (поскольку документы молчат в этом отношении).

Однако на основе GNU glibc 2.14.1 он на самом деле выделяет больше памяти, чем нужно, а затем скриптит с арены, чтобы освободить предварительное пространство и пост-пространство, так что возвращаемый адрес является "реальным" адресом, пригодным для использования на free или realloc.

Но, как указано, документация не гарантирует этого.

Ответ 2

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

Ответ 3

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