C - Variable-Length Arrays in C
A Variable-Length Array (VLA) is an array in C whose size is determined at runtime, rather than being fixed when the program is compiled. VLAs were introduced in the C99 standard and allow programmers to create arrays whose size depends on a value available during program execution.
1. What is a Variable-Length Array?
Normally, when declaring an array, its size is specified as a constant:
int numbers[10];
Here, the array can store exactly 10 integers, and its size is fixed.
With a variable-length array, the size can be determined from a variable:
int n;
printf("Enter the number of elements: ");
scanf("%d", &n);
int numbers[n];
In this example, the user enters the value of n while the program is running. The array numbers is then created with that many elements.
For example, if the user enters:
5
the program creates an array capable of storing five integers.
If the user enters:
100
the array contains 100 integers.
2. Basic Syntax
The general syntax for a VLA is:
data_type array_name[size];
where size is determined at runtime.
Example:
int n = 8;
int marks[n];
Here, marks contains eight integer elements.
Another example:
int size;
scanf("%d", &size);
float prices[size];
The number of elements in prices depends on the value entered by the user.
3. Why Use Variable-Length Arrays?
VLAs are useful when the required array size is not known until the program starts running.
Consider a program that asks a user how many students are in a class:
int students;
printf("Enter number of students: ");
scanf("%d", &students);
int marks[students];
It would be inconvenient to create a fixed-size array such as:
int marks[1000];
if only a small number of students are present.
A VLA allows the program to create an array based on the actual requirement.
4. Example Program
#include <stdio.h>
int main()
{
int n, i;
printf("Enter the number of elements: ");
scanf("%d", &n);
int numbers[n];
printf("Enter %d numbers:\n", n);
for (i = 0; i < n; i++)
{
scanf("%d", &numbers[i]);
}
printf("The numbers are:\n");
for (i = 0; i < n; i++)
{
printf("%d ", numbers[i]);
}
return 0;
}
If the user enters:
4
and then enters:
10 20 30 40
the program creates an array of four integers and stores these values.
The output will be:
The numbers are:
10 20 30 40
5. How VLA Size Is Determined
The important characteristic of a VLA is that its size does not have to be a compile-time constant.
For example:
int n;
scanf("%d", &n);
int arr[n];
The compiler does not know the value of n when the program is compiled. The size is determined when the program executes.
This is different from:
#define SIZE 10
int arr[SIZE];
Here, SIZE is known during preprocessing and the array has a fixed size.
6. VLA Inside a Function
VLAs are particularly useful inside functions.
#include <stdio.h>
void display(int n)
{
int numbers[n];
for (int i = 0; i < n; i++)
{
numbers[i] = i + 1;
}
for (int i = 0; i < n; i++)
{
printf("%d ", numbers[i]);
}
}
int main()
{
display(5);
return 0;
}
When display(5) is called, the function creates a VLA containing five integers.
If the function is called as:
display(20);
the VLA contains 20 integers.
7. Multidimensional Variable-Length Arrays
VLAs can also have multiple dimensions.
Example:
int rows, columns;
printf("Enter rows and columns: ");
scanf("%d %d", &rows, &columns);
int matrix[rows][columns];
Suppose the user enters:
3 4
The program creates a matrix containing three rows and four columns.
Values can be accessed in the normal way:
matrix[0][0] = 10;
matrix[1][2] = 20;
matrix[2][3] = 30;
A complete example is:
#include <stdio.h>
int main()
{
int rows, columns;
int i, j;
printf("Enter rows and columns: ");
scanf("%d %d", &rows, &columns);
int matrix[rows][columns];
printf("Enter matrix elements:\n");
for (i = 0; i < rows; i++)
{
for (j = 0; j < columns; j++)
{
scanf("%d", &matrix[i][j]);
}
}
printf("Matrix:\n");
for (i = 0; i < rows; i++)
{
for (j = 0; j < columns; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
8. VLA and Memory Allocation
A VLA is generally created with automatic storage duration when declared inside a block or function.
For example:
void test(int n)
{
int arr[n];
}
The array exists while execution remains within the relevant block. When the block is exited, the VLA's lifetime ends.
This is different from dynamically allocated memory:
int *arr = malloc(n * sizeof(int));
Here, memory is explicitly allocated and remains allocated until it is released using:
free(arr);
Therefore, a VLA and a dynamically allocated array are not the same thing.
9. VLA vs Fixed-Length Array
| Feature | Fixed-Length Array | Variable-Length Array |
|---|---|---|
| Size | Fixed | Determined at runtime |
| Example | int a[10]; |
int a[n]; |
| Size known at compilation | Usually yes | No |
| Size can depend on user input | No | Yes |
| Storage management | Automatic for local arrays | Automatic for local VLAs |
| Resizable after creation | No | No |
Requires malloc() |
No | No |
One important point is that a VLA cannot be resized after it has been created. If the program needs an array whose size can actually change during its lifetime, dynamic memory allocation is generally more appropriate.
10. VLA vs Dynamic Array
These two concepts are often confused.
A VLA:
int arr[n];
A dynamically allocated array:
int *arr = malloc(n * sizeof(int));
The VLA is automatically managed according to its scope, whereas dynamically allocated memory must be explicitly released:
free(arr);
Dynamic allocation is generally more flexible when memory needs to survive beyond the current block or when the program needs to resize the allocation.
11. Advantages of VLAs
VLAs provide several useful features:
Runtime-sized arrays:
The programmer does not need to know the array size in advance.
Simple syntax:
The declaration is straightforward:
int arr[n];
Useful for temporary data:
They can be convenient for short-lived arrays inside functions.
No explicit malloc() required:
For a VLA, the programmer does not have to manually allocate and free memory.
Useful for matrices:
VLAs make it easier to create multidimensional arrays where dimensions are determined at runtime.
12. Limitations of VLAs
VLAs also have limitations.
Large VLAs can cause stack problems.
For example:
int arr[100000000];
If a similarly large VLA is created on a stack with limited available space, the program may fail.
They cannot be resized.
Once:
int arr[n];
has been created, changing n does not resize arr.
Compiler support varies.
VLA support depends on the C language standard and compiler. Some modern C environments, particularly those using newer language modes or extensions, may not support VLAs in the same way.
They are mainly suited to automatic storage.
For very large or long-lived data, dynamic memory allocation is often a better choice.
13. Important Example
Consider:
#include <stdio.h>
int main()
{
int n;
printf("Enter array size: ");
scanf("%d", &n);
if (n <= 0)
{
printf("Invalid array size.\n");
return 1;
}
int numbers[n];
for (int i = 0; i < n; i++)
{
numbers[i] = i * 10;
}
for (int i = 0; i < n; i++)
{
printf("%d ", numbers[i]);
}
return 0;
}
If the user enters 5, the VLA is equivalent in size to:
int numbers[5];
If the user enters 10, it becomes equivalent in size to:
int numbers[10];
The declaration itself remains:
int numbers[n];
and n is evaluated during program execution.
14. Important Points to Remember
A Variable-Length Array is an array whose length is determined during program execution.
The basic form is:
int arr[n];
where n is a runtime value.
VLAs are especially useful when the required size is unknown until the program receives input or calculates a value.
They are different from dynamically allocated arrays created with malloc(). A VLA generally has automatic lifetime within its scope, while dynamically allocated memory is explicitly managed by the programmer.
The most important distinction is:
int arr[10]; // fixed-size array
versus:
int n = 10;
int arr[n]; // variable-length array
and:
int *arr = malloc(n * sizeof(int)); // dynamically allocated array
Understanding these three approaches is important because they represent different ways of handling arrays and memory in C.