Webinar: Evaluation - 05.12
A variable-length array is an array whose length is determined at runtime. Despite its confusing name, once declared, the length of this array cannot be changed at runtime. An array whose length can be changed at runtime is called a dynamic array.
Variable-length arrays are optionally available in C since C99 and mandatory since C23. In C++, variable-length arrays are available in non-standard extensions (for example, in GCC). Instead of them, you can use the non-standard alloca function to allocate memory on a stack or the standard std::vector container to manage memory on a heap.
The variable-length array is declared as follows:
void foo()
{
size_t n = ....;
// ....
int32_t arr[n];
....
}
The size of an array is determined at run time when an array is declared. Note that the changes of the n variable do not affect the size of the arr array once it is declared:
size_t n = 3;
int32_t arr[n]; // sizeof(arr) == 12
n = 7; // sizeof(arr) == 12
A variable-length array can have either automatic or dynamic lifetime, depending on the implementation. If an array has an automatic lifetime, it is allocated on the stack. If an array has a dynamic lifetime, it is allocated on a heap. In both cases, the array is deallocated when leaving the scope. If a variable-length array is allocated on a stack, there is a risk of stack overflow if the size of the array is set too large.
A variable-length array can also be declared as a function parameter. The size can be specified with a '*' (this is only allowed when declaring formal parameters and only in the function prototype), in which case the array has an unspecified size. Look at the example of declaration:
int sum(size_t n, int arr[*]);
When a variable-length array is passed, it is passed through a pointer just like regular arrays. So, sizeof(arr) == sizeof(int *).
Let's examine the use of a variable-length array in practice. Suppose we need to find the sum of an arbitrary amount of numbers. Since the amount of numbers is unknown at compile time, we should use the variable-length array:
int32_t get_int32_t();
int32_t sum_impl(size_t, int32_t arr[*]);
int32_t sum_impl(size_t n, int32_t arr[n])
{
int32_t sum = 0;
for (size_t i = 0; i < n; ++i)
{
sum += arr[i];
}
return sum;
}
int32_t sum(size_t n)
{
int32_t array[n];
for (size_t i = 0; i < n; ++i)
{
array[i] = get_int32_t();
}
return sum_impl(n, array);
}
In this example, the int32_t arr[n] argument is equivalent to int32_t *arr. We write the pointer in such a way that the person reading the code knows that a variable-length array (not a regular pointer) is expected as the second argument of the function.
0