Как указывали другие, последний член структуры не имеет установленного размера. Однако длина массива, по мнению реализации, должна быть достаточной для размещения символов, которые она хочет в него поместить. Он делает это путем динамического выделения памяти для структуры, например, с malloc
.
Однако удобно объявить член размером 1, потому что легко определить, сколько памяти занято любой dirent
переменной d
:
sizeof(dirent) + strlen(d.d_name)
Использование размера 1 также препятствует тому, чтобы получатель таких значений структуры пытался сохранить в нем свои собственные имена вместо того, чтобы выделять свои собственные dirent
значения. Используя определение Linux, разумно предположить, что любое имеющееся у вас значение dirent
будет принимать строку из 255 символов, но Solaris не дает никаких гарантий, что в его значениях dirent
будет храниться больше символов, чем необходимо.
Я думаю, что именно C 99 ввел особый случай для последнего члена структуры. Вместо этого структуру можно было бы объявить так:
typedef struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name[];
} dirent_t;
У массива нет заявленного размера. Это известно как гибкий элемент массива. Он выполняет то же самое, что и версия Solaris, за исключением того, что нет иллюзий, что структура сама по себе может содержать любое имя. Глядя на это, вы понимаете, что это еще не все.
Используя "гибкое" объявление, объем занимаемой памяти можно отрегулировать следующим образом:
sizeof(dirent) + strlen(d.d_name) + 1
Это потому, что гибкий член массива не влияет на размер структуры.
Причина, по которой вы не видите подобные гибкие объявления чаще, особенно в коде библиотеки ОС, скорее всего, связана с совместимостью со старыми компиляторами, которые не поддерживают эту возможность. Это также для совместимости с кодом, написанным для нацеливания на текущее определение, которое сломается, если размер структуры изменится таким образом.
person
Rob Kennedy
schedule
18.02.2009