Массивы переменной длины (VLA — Variable Length Arrays) появились в стандарте C99, до этого все размеры массивов должны были быть известны на этапе компиляции. Позволяют объявлять массивы, размер которых определяется переменной, известной только во время выполнения.
Неверное использование VLA приводит к необработанным ошибкам выделения памяти (например, слишком большой размер массива приведёт к stack overflow), невозможности передать VLA между разными компиляторами (не все их поддерживают), и ограниченной совместимости с более старыми стандартами C и C++. Также отладки осложняются тем, что память выделяется на стеке, а не в куче, что не всегда ожидаемо.
Используя VLA, нужно помнить, что они живут на стеке и не могут быть глобальными или статическими. Лучше предпочитать динамические массивы через malloc, если необходима гибкость и гарантированное взаимодействие с C++. Для совместимости стоит ограничиться статическими массивами или стандартами C90, если поддержка VLA не гарантирована.
Пример кода:
#include <stdio.h> void process(size_t n) { int arr[n]; // VLA for(size_t i = 0; i < n; i++) arr[i] = i; for(size_t i = 0; i < n; i++) printf("%d ", arr[i]); } int main() { process(5); return 0; }
Ключевые особенности:
Можно ли объявить статический массив переменной длины как static int arr[n]; внутри функции?
Нет, статические переменные должны иметь определённый размер на этапе компиляции. Поэтому static int arr[n]; с переменным размером вызовет ошибку компиляции.
Будут ли VLA автоматически освобождены при выходе из функции?
Да, VLA размещаются на стеке и их память освобождается автоматически при выходе из блока/функции, так же как у обычных локальных переменных.
Безопасно ли выделять VLA очень большого размера?
Нет, размер стека ограничен (например, 1 МБ или 8 МБ). Попытка выделить большой VLA приведёт к ошибке выполнения (stack overflow).
Писали кросс-платформенный код с VLA, код не компилировался на старых или строго настроенных компиляторах.
Плюсы:
Минусы:
Использовали VLA только для локальных задач и там, где гарантирован небольшой размер, для крупных массивов — malloc/free.
Плюсы:
Минусы: