﻿# Variable\-length array

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](https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html)\)\. 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:

```cpp
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:

```cpp
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](https://pvs-studio.com/en/blog/terms/6564/), 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:

```cpp
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:

```cpp
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\.