Как уже отмечали другие, последний член структуры не имеет установленного размера. Массив однако длинный, реализация решает, что он должен быть вмещать символы, которые он хочет вставить в него. Это достигается путем динамического выделения памяти для структуры, например, с помощью 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
Это потому, что член гибкого массива не учитывает размер структуры.
Причина, по которой вы не видите таких гибких объявлений, как это, особенно в коде библиотеки ОС, скорее всего, ради совместимости со старыми компиляторами, которые не поддерживают эту возможность. Это также для совместимости с кодом, написанным для текущего определения, которое сломалось бы, если бы размер структуры изменился таким образом.