C типы данных struct могут заканчиваться гибким массивом элементом без указанного размера:
struct vectord {short len; // должен быть хотя бы один другой член данных double arr; // гибкий член массива должен быть последним // Компилятор может зарезервировать здесь дополнительное пространство для заполнения, как это может быть между элементами структуры};
Обычно такие структуры служат заголовком в более крупном, распределении памяти для переменных :
struct vectord * vector = malloc (...); вектор->len =...; для (int i = 0; i < vector->len; i ++) vector->arr [i] =...; // прозрачно использует правильный тип (double)
Оператор sizeof
на такой struct
дает размер структуры, как если бы элемент гибкого массива был пустым. Это может включать в себя набивку, добавленную для размещения гибкого элемента; компилятор также может повторно использовать такое заполнение как часть самого массива.
Обычно выделяют sizeof (struct) + array_len * sizeof (элемент массива)
байтов.
В этом нет ничего плохого, однако он может выделить на несколько байтов больше, чем необходимо: компилятор может изменить назначение некоторых дополнений, которые включены в sizeof (struct)
. Если это вызывает беспокойство, доступны макросы для вычисления минимального размера, гарантируя, что заполнение компилятора не будет нарушено.
Поскольку массив может начинаться с заполнения до конца структуры, к его содержимому всегда следует обращаться через индексирование (arr [i]
) или offsetof
, not sizeof
.
Гибкие элементы массива были официально стандартизированы в C99, однако компиляторы принимали элементы массива нулевого размера с тем же эффектом (например, GCC, Microsoft Visual C ).
Гибкие элементы массива официально не являются частью C ++, но такие же расширения совместимости существуют.