Тип данных в K & R:
union header
{
struct
{
union header *ptr;
unsigned size;
} s;
Align x;
};
Допустим, у нас было это вместо:
union header_t
{
struct
{
union header_t *next;
unsigned size;
} s;
};
(Кстати, вам нужно имя для переменной struct
, а также изменить
указатель внутри struct
для ввода union header_t *
, потому что
структура данных представляет собой связанный список.)
Реализация
K & R malloc()
резервирует часть пространства, а затем
использует это для поддержания свободного магазина. Когда это malloc
называется, оно
находит в свободном списке место, которое имеет достаточно места, и возвращает
указатель на этот хвостовой конец.
В частности, соответствующая часть кода:
typedef union header Header;
static Header base;
Header *p = &base;
...
p += p->s.size;
return (void *)(p+1);
Обратите внимание, что мы возвращаем p+1
(приведение к void *
), поэтому мы должны убедиться, что этот указатель выровнен для любого типа данных . Поскольку p
сам указывает на Header *
, мы должны убедиться, что когда мы добавляем sizeof(Header)
к выровненному указателю, мы получим еще один выровненный указатель назад (помните, p+1
указывает на sizeof(Header)
байт из p
). Это требование означает, что Header
имеет для выравнивания для всех типов данных.
struct
внутри Header
может быть не выровнено для максимально широкого типа . Чтобы убедиться, что наш тип Header
выровнен так, мы добавляем элемент к union
, который, как мы знаем, максимально выровнен, то есть самый широкий тип на данной машине. K & R предполагает, что этот тип long
. Также обратите внимание, что не имеет значения, больше ли размер Header
, чем размер типа Align
. Здесь предполагается, что тип Align
здесь - это тип с строжайшими требованиями к выравниванию, а не то, что он будет огромным.
Интересно, что нам нужно предположить тип «максимально выровненный», потому что стандарт C требует выравнивания для любого типа по указателям, возвращаемым malloc
, но не указывает переносимый способ выяснить, что это за выравнивание будет. Если стандарт действительно определяет такой тип, можно было бы использовать этот тип вместо long
для Align
.