Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What technical disadvantages do C99-style VLAs have? [closed]

I heard from many people that variable length array, introduced in C99, are terrible. Some guys on IRC said a minute ago « I don't think C++ will get VLA's, strousoup made some very negative comments about them ».

What are the reasons why those people hate VLAs?

like image 766
qdii Avatar asked Sep 13 '12 13:09

qdii


People also ask

Should I use VLAs?

If you are sure that n is 2,3 or at most 4 there's no reason to avoid VLA due to stack scare, and they may make your code much simpler, clearer and better. On the other hand, VLA are useful even if you do not use them to allocate memory.

How do you prevent VLA?

You can alloca() memory in a loop for example and use the memory outside the loop, a VLA would be gone because the identifier goes out of scope when the loop terminates.

Why is variable-length array bad?

Declaring variable-length arrays can lead to a stack overflow and potential vulnerabilities in the program. Consider the example: void foo(size_t n) { int arr[n]; // .... } Transmission of large number 'n' can lead to a stack overflow as the array will become too large and take up more memory than it really is.

What is VLA in C language?

In computer programming, a variable-length array (VLA), also called variable-sized or runtime-sized, is an array data structure whose length is determined at run time (instead of at compile time). In C, the VLA is said to have a variably modified type that depends on a value (see Dependent type).


2 Answers

As others have pointed out, VLAs make it really easy to overflow your stack frame. I'm not a compiler writer, but my understanding is that VLAs can also be a bugger to support (they are now optional in C2011). And their use is limited to block or function scope; you cannot use a VLA at file scope, and they can't have external linkage.

I wouldn't want to see VLA syntax go away, though; it comes in really handy when dynamically allocating multi-dimensional arrays where the inner dimensions are not known until runtime, such as:

size_t r, c;
// get values for r and c
int (*arr)[c] = malloc(r * sizeof *arr);
if (arr)
{
   ...
   arr[i][j] = ...;
   ...
   free(arr);
}

One contiguous allocation (and one corresponding free), and I can subscript it as a 2D array. The alternatives usually mean piecemeal allocation:

size_t r, c;
...
int **arr = malloc(sizeof *arr * r);
if (arr)
{
  for (i = 0; i < c; i++)
    arr[i] = malloc(sizeof *arr[i] * c);
  ...
  arr[i][j] = ...;
  ...
  for (i = 0; i < c; i++)
    free(arr[i]);
  free(arr);
}

or using 1-d offsets:

int *arr = malloc(sizeof *arr * r * c);
if (arr)
{
  ...
  arr[i * r + j] = ...;
  ...
  free(arr);
}
like image 172
John Bode Avatar answered Oct 12 '22 11:10

John Bode


VLAs allocate arrays on the stack, in runtime, making it harder, or even impossible to determine the stack size used at compile time. Since the stack has a rather small amount of memory available (in comparison with the heap), many worry that VLAs have a great potential for stack overflow.

The upcoming version of the MISRA-C coding standard is most likely going to ban VLAs as well.

like image 24
Lundin Avatar answered Oct 12 '22 11:10

Lundin