6.19 Массивы переменной длины
Автоматические массивы переменной длины разрешены в ISO C99, и в качестве расширения GCC принимает их в режиме C90 и в C++. Эти массивы объявляются как и любые другие автоматические массивы, но с длиной, которая не является константным выражением. Память выделяется в момент объявления и освобождается, когда область видимости блока, содержащего объявление, завершается. Например:
FILE *
concat_fopen (char *s1, char *s2, char *mode)
{
char str[strlen (s1) + strlen (s2) + 1];
strcpy (str, s1);
strcat (str, s2);
return fopen (str, mode);
}
Выход из области видимости имени массива или прерывание выполнения в этой области освобождает выделенную память. Вход в область видимости не допускается; для этого вы получите сообщение об ошибке.
В качестве расширения GCC принимает массивы переменной длины в качестве члена структуры или объединения. Например:
void
foo (int n)
{
struct S { int x[n]; };
}
Вы можете использовать функцию alloca для получения эффекта, аналогичного массивам переменной длины. Функция alloca доступна во многих других реализациях C (но не во всех). С другой стороны, массивы переменной длины более элегантны.
Существуют и другие различия между этими двумя методами. Память, выделенная с помощью alloca, существует до тех пор, пока не вернётся содержащая её функция. Память для массива переменной длины освобождается как только заканчивается область видимости имени массива, если вы также не используете alloca в этой области.
Вы также можете использовать массивы переменной длины в качестве аргументов функций:
struct entry
tester (int len, char data[len][len])
{
/* … */
}
Длина массива вычисляется один раз при выделении памяти и запоминается для области видимости массива на случай, если вы обращаетесь к ней с помощью sizeof.
Если вы хотите передать массив сначала, а затем длину, вы можете использовать объявление вперёд в списке параметров — ещё одно расширение GNU.
struct entry
tester (int len; char data[len][len], int len)
{
/* … */
}
'int len' перед точкой с запятой является объявлением параметра вперёд, и оно служит для того, чтобы имя len стало известным при парсинге объявления data.
Вы можете написать любое количество таких объявлений параметров вперёд в списке параметров. Они могут быть разделены запятыми или точками с запятой, но последнее должно заканчиваться точкой с запятой, за которой следуют «действительные» объявления параметров. Каждое объявление вперёд должно соответствовать «действительному» объявлению по имени параметра и типу данных. ISO C99 не поддерживает объявления параметров вперёд.
Далее: Макросы с переменным числом аргументов, Предыдущее: Пустые структуры, Вверх: Расширения C [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-6.5.0/gcc/Variable-Length.html