#c
Вопрос:
Я пытаюсь создать mymalloc в программировании на c с 8-байтовым выравниванием. Но я нахожу проблему, если есть 4-байтовый заголовок и 8-байтовая полезная нагрузка(распределенные данные),
Нужно ли нам выделять 16 байт, чтобы соответствовать выравниванию, или мы заботимся только о выравнивании полезной нагрузки?
Комментарии:
1. Таким образом, в вашем malloc есть указатель на заголовок на четырехбайтовой границе, а указатель, передаваемый вызывающему, должен находиться на границе восьми байтов?
2. Не могли бы вы объяснить это подробнее?
we only care about the alignment of payload?
Кто такие «мы»? Пользователь библиотеки заботится только о полезной нагрузке. Вы пишете свой собственный mymalloc, поэтому можете решить, нужно ли выравнивать заголовок или нет.3. Да, мы должны выделить 16 байт, если заголовок выровнен по 8 байтам
4. @JerryJeremiah Я пытаюсь создать блок, содержащий как заголовок, так и полезную нагрузку, поэтому, если мне интересно, всего ли у меня 12 байт, нужно ли мне выделять 16 байт для выравнивания?
5.Это зависит от того, на какой «обычный malloc» вы хотите посмотреть — каждая «реализация стандартной библиотеки C» поставляется с собственной реализацией malloc. Вы можете проверить: github.com/lattera/glibc/blob/master/malloc/malloc.c#L1059 github.com/eblot/newlib/blob/master/newlib/libc/stdlib/…github.com/esmil/musl/blob/master/src/malloc/malloc.c#L356 также jemalloc , dlmalloc и т.д.
Ответ №1:
Согласно C 2018 7.22.3 1, malloc
возвращает память, достаточно выровненную для любых основных требований к выравниванию. Реализация C может определить ее наибольшее фундаментальное выравнивание, и этого достаточно для всех базовых типов, типов перечисления и указателей, а также массивов, структур и объединений, члены которых имеют фундаментальные требования к выравниванию, а также для всех полных типов объектов в стандартной библиотеке C. Вы можете найти фундаментальное соответствие с. _Alignof (max_align_t)
Давайте назовем это F.
Если вы используете malloc
для использования памяти в своем mymalloc
, вы будете использовать несколько байтов (меньше F) для своих собственных данных, и вы хотите, чтобы возвращаемый адрес имел выравнивание F, тогда вам нужно запросить malloc
на F байтов больше, чем объем памяти, запрошенный вызывающим абонентом. Это malloc
связано с тем, что будет возвращен некоторый адрес A с выравниванием F (или лучше), и после размещения там ваших данных вы должны вернуть пользователю какой-то адрес, больший, чем этот. Следующий адрес с выравниванием F равен A F, поэтому блок памяти в точке A будет содержать F байтов, за которыми следуют данные пользователя. Следовательно, вам нужно попросить malloc
F байт плюс сумма, запрошенная вызывающим абонентом.