Is there any overhead for using variable length arrays?

Is there any overhead for using variable length arrays? Can the array size be passed through a command line argument at run time? Why is this introduced compared to automatic and dynamic array allocation?

+43
c arrays variable-length-array
Jan 9 '10 at 19:55
source share
4 answers

VLA has some overhead (compared to a "regular" array with a compilation type name).

Firstly, it has a run-time length, and yet the language provides you with the means to get the actual size of the array at runtime (using sizeof ). This immediately means that the actual size of the array must be saved somewhere. This leads to some negligible memory overhead for each array. However, since VLAs can only be declared as automatic objects, this overhead is not something anyone would notice. This is similar to declaring an additional local variable of integral type.

Secondly, a VLA is usually allocated on the stack, but because of its variable size, in general, its exact location in memory is unknown at compile time. For this reason, the base implementation should usually implement it as a pointer to a block of memory. This introduces some additional memory overhead (for the pointer), which again is completely negligible for the reasons described above. This also leads to minor overhead, since we have to read the pointer value to find the actual array. These are the same overheads that you get when accessing malloc -ed arrays (and don't get with arrays with the specified compile-time size).

Since the VLA size is an integer run-time value, it can, of course, be passed as a command line argument. VLA does not care where its size comes from.

VLAs were presented as run-time arrays with low allocation / release costs. They fit between "regular" named arrays of compile-time size (which have a practically zero distribution-free cost but a fixed size) and malloc -ed arrays (which have a run-time size but a relatively high allocation-free cost).

VLAs obey [almost] the same volume-dependent rules of life as automatic (that is, local) objects, which means that in general they cannot replace malloc -ed arrays. They apply to situations where you need an array with fast runtime with typical battery life.

+43
Jan 09 '10 at
source share

Overhead at runtime with variable length arrays, but you will have to work hard enough to measure them. Note that sizeof(vla) not a compile-time constant if vla is a variable-length array.

The size of the array can be passed to the function at run time. If you decide to take the size from the command line argument and convert it to an integer and pass it to the function at run time, let it be so - it will work.

Variable-length arrays are used because the variables are automatically allocated to the correct size and automatically freed when they exit the function. This avoids over-allocation of space (allocating enough space for the largest possible size when you mostly work with the smallest size), and avoids problems with clearing the memory.

In addition, with multidimensional arrays, AFAIK behaves more like Fortran - you can dynamically tune all dimensions, rather than get stuck with fixed sizes for all but the leading dimension of the array.




Concrete evidence of some run-time overhead for VLAs — at least from GCC 4.4.2 to SPARC (Solaris 10).

Consider the two files below:

vla.c - using an array of variable length

 #include <assert.h> #include <stddef.h> extern size_t identity_matrix(int n, int m); size_t identity_matrix(int n, int m) { int vla[n][m]; int i, j; assert(n > 0 && n <= 32); assert(m > 0 && m <= 32); for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { vla[i][j] = 0; } vla[i][i] = 1; } return(sizeof(vla)); } 

fla.c - using a fixed-length array

 #include <assert.h> #include <stddef.h> extern size_t identity_matrix(int n, int m); size_t identity_matrix(int n, int m) { int fla[32][32]; int i, j; assert(n > 0 && n <= 32); assert(m > 0 && m <= 32); for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { fla[i][j] = 0; } fla[i][i] = 1; } return(sizeof(fla)); } 

Compilation and object file sizes

For comparison purposes, the names of the local array are different ( vla vs fla ), and the sizes in the array are different when they are declared - otherwise the files are the same.

I compiled using:

 $ gcc -O2 -c -std=c99 fla.c vla.c 

The size of the object file is slightly different - both "ls" and "size" are measured:

 $ ls -l fla.o vla.o -rw-r--r-- 1 jleffler rd 1036 Jan 9 12:13 fla.o -rw-r--r-- 1 jleffler rd 1176 Jan 9 12:13 vla.o $ size fla.o vla.o fla.o: 530 + 0 + 0 = 530 vla.o: 670 + 0 + 0 = 670 

I did not conduct detailed testing to find out how much overhead has been fixed and how many variables, but there is overhead when using VLA.

+27
Jan 09
source share

I'm just wondering if there is overhead for using variable length arrays?

Nope

Can the array size be passed through a command line argument at run time?

Yes.

Why is this introduced compared to automatic and dynamic array allocation?

Auto-allocation only allows a fixed size known at compile time.

Dynamic allocation ( malloc ) will store the array on the heap, which has a large memory space but is slower to access.

VLA works by pushing an array onto the stack. This makes allocation and access extremely fast, but usually the stack is small (from a few kilobytes), and when the VLA overflows the stack, it is indistinguishable from infinite recursion.

+3
Jan 09
source share

There should be very little overhead for the VLA (at most, this should add a stack pointer). Dynamic allocation requires manual memory management and is slower than a stack-based VLA allocation, and compilation time expression for the size of the array is required for an "automatic" array declaration. However, keep in mind that if a stack overflow occurs, this will lead to undefined behavior, so keep the VLA relatively small.

You can pass the size of the array using the command line argument, but you will have to write code to process it.

+1
Jan 09
source share



All Articles