Первый элемент - просто указать, что элемент в структуре использует синтаксис массива, но на самом деле он не объявлен как массив любого размера.
Malloc выделяет круговой размер буфера (который учитывает все неключевые поля) и ключевые поля (size * sizeof (KeyType)). Обратите внимание, что ключи [0] на самом деле имеют нулевой размер, поэтому ни одно поле ключа не учитывается дважды.
Буфер на самом деле не больше, чем размер циклического буфера, выделение (как описано выше) было однократным выделением для размещения циклического буфера и элементов управления (size, readPointer, writePointer) за один проход .
Вся причина в том, что это работает, потому что C не проверяет, прошел ли ты конец массива. В языке, который устанавливает границы массивов, при первой попытке использовать это вы получите что-то похожее на ArrayOutOfBoundsException в Java, потому что для использования keys [0] вы должны были бы объявить массив ключей размером (по крайней мере) один, как клавиши [1].
Другими словами, это пара специфичных для C хаков, чтобы оптимизировать распределение буфера один раз, без кодирования фиксированного размера. Это работает потому, что смещение массива строго реализовано как (базовый адрес + индекс * sizeof (тип массива)).