Существуют некоторые накладные расходы во время выполнения с массивами переменной длины, но вам придется приложить немало усилий, чтобы измерить их. Обратите внимание, что sizeof(vla)
не является константой времени компиляции, если vla
является массивом переменной длины.
Размер массива может быть передан функции во время выполнения. Если вы решите взять размер из аргумента командной строки, преобразовать его в целое число и передать его функции во время выполнения, пусть будет так - это будет работать.
Используются массивы переменной длины, поскольку переменные автоматически присваиваются правильному размеру и автоматически освобождаются при выходе из функции. Это позволяет избежать перераспределения пространства (выделяя достаточно места для максимально возможного размера, когда вы в основном работаете с минимальными размерами) и избегает проблем с очисткой памяти.
Кроме того, с многомерными массивами AFAIK он ведет себя больше как Fortran - вы можете динамически конфигурировать все измерения, вместо того, чтобы застрять с фиксированными размерами для всех, кроме ведущего размера массива.
Конкретные доказательства некоторых накладных расходов во время выполнения для VLA - по крайней мере, с GCC 4.4.2 на SPARC (Solaris 10).
Рассмотрим два файла ниже:
vla.c - использование массива переменной длины
#include <assert.h>
#include <stddef.h>
extern size_t identity_matrix(int n, int m);
size_t identity_matrix(int n, int m)
{
int vla[n][m];
int i, j;
assert(n > 0 && n <= 32);
assert(m > 0 && m <= 32);
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
vla[i][j] = 0;
}
vla[i][i] = 1;
}
return(sizeof(vla));
}
fla.c - использование массива фиксированной длины
#include <assert.h>
#include <stddef.h>
extern size_t identity_matrix(int n, int m);
size_t identity_matrix(int n, int m)
{
int fla[32][32];
int i, j;
assert(n > 0 && n <= 32);
assert(m > 0 && m <= 32);
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
fla[i][j] = 0;
}
fla[i][i] = 1;
}
return(sizeof(fla));
}
Компиляция и размеры объектных файлов
В целях сравнения имена локального массива отличаются (vla
против fla
), а размеры в массиве различаются, когда он объявляется - в противном случае файлы совпадают.
Я скомпилировал с помощью:
$ gcc -O2 -c -std=c99 fla.c vla.c
Размеры объектных файлов несколько отличаются - измеряются как 'ls', так и 'size':
$ ls -l fla.o vla.o
-rw-r--r-- 1 jleffler rd 1036 Jan 9 12:13 fla.o
-rw-r--r-- 1 jleffler rd 1176 Jan 9 12:13 vla.o
$ size fla.o vla.o
fla.o: 530 + 0 + 0 = 530
vla.o: 670 + 0 + 0 = 670
Я не проводил подробное тестирование, чтобы увидеть, какая часть служебных данных фиксирована и какая переменная, но при использовании VLA есть издержки.