Both variants have their pros and cons:
Advantages of Variable Length Arrays:
You do not waste memory. You can simply allocate as much memory as you need. This is most pronounced with strings: Usually, you want to allow for really long strings, even though most are really, really short. Allocating half a kilobyte for all strings is a huge waste of memory, even though allocating less might already be too tight a constraint.
You do not introduce artificial limits. Since you allocate precisely as much memory as is dynamically needed, you do not burden your users with upper limits on how long a name/path/file/whatever can be.
Disadvantages of Variable Length Arrays:
- You cannot allocate arbitrarily large arrays on the stack. Even if your system can automatically grow your stack, you can still segfault your program by allocating an array that makes the stack pointer jump across the sentinel pages used by your OS. A few kilobytes is generally ok, a few megabytes is not.
Advantages of fixed size buffers:
Easy to set up.
They are C++. The C++11 standard explicitly disallows an array type from having a runtime size, even though C even allows you to typedef a variable length array since C99 (void foo(int n) { typedef int (*)[n]; ... }
is perfectly legal C99, but you can't write void foo(int n) { int bar[n]; }
in C++11).
Disadvantages of fixed size buffers:
They tend to burden the user with fixed limits. Sure, you can try to handle situations where you would normally need more memory, but in most cases, the limitations are just forwarded to the user who will be very unhappy about it one day.
They invite bugs via buffer overruns. You program needs to handle all errors due to exceeded array sizes explicitly and correctly. One mistake in this error handling code, and your program crashes in a way that is likely a security vulnerability. With variable length arrays, you never get into the situation of overrunning a buffer, because you always allocate your buffer large enough for the job.
All in all, I believe #define N ...
and int foo[N];
is almost always bad style. If you can prove a low maximum size and you are not writing C++, go with Variable Length Arrays. If you can't malloc()
/new
the array. Only if you can prove that you can never require more than a very specific size (as in "a quartic root solver will never return more than four roots"), go ahead an use a fixed size. Personally, I allocate almost all arrays with malloc()
/new
.