C99 introduced variable-length arrays (VLAs), a feature which is often
misunderstood and surrounded in controversy. The issue is that, unlike with malloc
,
trying to allocate an array too large cannot be robustly handled, but instead can cause the
silent crashing of applications, or worse.
If one has to guard the size of a VLA so that it doesn't exceed a safe maximum, one might
as well always allocate that safe maximum.
However, pointers to VLAs allocated on the heap can still be useful, especially in the case
of multidimensional arrays.
There are however a couple criterion where using VLAs on the stack, or even the non-standard
alloca
function, is justifiable. That is
On embedded devices, there may not be any access to malloc
at all. Then, or when there's a
significant chance of malloc
failing, using a VLA may be appropriate. For example, consider
error handling with the POSIX
regular expression
functions. One legitimate reason for them to fail is being out of memory for dynamic allocation; it may not be possible
to allocate the string describing the error on the heap.
#define _POSIX_C_SOURCE 200809L
#include <regex.h>
#include <stdio.h>
int main(void) {
regex_t reg;
int i = regcomp(®, "(", REG_EXTENDED);
if(i) {
size_t buflen = regerror(i, ®, NULL, 0);
char errorstr[buflen];
regerror(i, ®, errorstr, sizeof(errorstr));
fputs(errorstr, stderr);
} else {
regfree(®);
}
}
Here we use regcomp
to try to compile the extended regular expression "(", and
if we get a non-zero error code, we call regerror
to get a string describing what
the problem was. Note that regerror
is snprintf
-like: it takes a buffer
to store the string in as well as the size of that buffer, but if you pass a NULL
pointer and length zero, you can use the return value to figure out how big of a buffer you need.