1

Whenever I need to create an array with a number of elements not known until execution time I do this.

int n, i;
printf("Number of elements: ");
scanf("%d", &n);
int myArray[n];
for(i = 0; i < n; i++)
    myArray[i] = 0;

However I've been told by 3 people with a PhD in Computer Science not to do it, because "it's not guaranteed to work on every compiler", and that the number of the elements in an array must be known at compile-time. So they do that like this.

int myArray[1000];
int n, i;
printf("Number of elements: ");
scanf("%d, &n);
//we must stop at the n element
for(i = 0; i < n; i++)
    myArray[i] = 0;

Which one should I use? When it's not guaranteed to work? Is it just a memory waste or a need to maintain legacy?

5
  • Use dynamic memory allocation if you want to implement dynamic arrays in C. Commented Jul 29, 2016 at 19:21
  • 3
    Neither. Use something like int * myArray = malloc( n * sizeof *myArray); and do your cleanup later when finished. Commented Jul 29, 2016 at 19:22
  • It is completely compiant to the C99 version of the standard. It is called variable length array (VLA). Due to some unknow reason, the commitee made VLAs optional in the current version (C11) - against their established practice of backwards-compatibility at all cost. I'd still recommend to use it. A modern desktop compiler will support it (e.g. gcc and clang). Don't use outdated compilers like MSVC. They have other problems with modern C, too. Sometimes one has to make a cut. WQe don't use horse-cariages either anymore. Or morse emails. Your PhDs should move on Commented Jul 29, 2016 at 19:58
  • @clarasoft-it: A VLA is not a dynamically allocated array, but a normal automatic variable. Commented Jul 29, 2016 at 20:19
  • Just in case my comment was not clear: Use VLAs, but make sure they will not overflow the stack (as for any other automatic variable!). Use modern compilers, no outdated rubbish from vendors who sell them for some 1k bucks/euros/etc. without going forward. Commented Jul 29, 2016 at 20:22

2 Answers 2

2

"it's not guaranteed to work on every compiler"

Yes, basically, correct.

The first approach, VLA, variable length array, was a part of C99 standard. However,

  • in C11, that has been made optional. You better not rely on that feature.
  • C89 did not have that as a port of the standard. gcc extensions were there, however, to support them.

Quoting C11, chapter §6.7.6.2/p5

[....] If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.)

As an alternative approach, you can always use a pointer and dynamic memory allocation like malloc() and family, if you have to rely on run-time values.

Taken together, to answer the question

Is creating array with a variable number of elements possible?

It is possible, but only with VLA support. Without that, you have to sate yourself with a pointer and memory allocation functions, at best.

Sign up to request clarification or add additional context in comments.

5 Comments

Hi Sourav! I stongly disagree with your conclusion not to use VLAs. Just because there's still people using horse-carriages does not mean all motorways shall have a speed-limt of 20 km/h. There are enough modern compilers which do support C99, thus VLAs. Compilers which do not support C99/full C11 likely don't support other features, too in modern C. C seems to be the only alnguage stuck to a 27 year old version just because people refuse to learn something new and request modern featurres from their vendors.
@Olaf Sir, thank you for the comments. First of all, I am not against VLAs, I just tried to suggest as alternative, as you can see. Secondly, I was trying to specify the compiler supports for each of them. If you think my answer in biased in any way, please suggest changes in wordings or feel free to modify. :)
Dynamic allocation is not a replacement for VLAs in general. Not only the functions are not available for most implementations - condidering most implementations are freestanding without the then not required parts of the standard library. Then they are not usable if you need multidimensional arrays, because you need a pointer to VLA for 2D already if you use dynamic allocation..
@Olaf You're very correct. Replacement, no. Alternative approach, yes. In case, VLAs are not around (not supported), then we have to work around them using pointer and malloc(), don't you agree? Also, VLAs are stack-size limited, at least in gcc, while malloc() is probably more generous. :)
No, the work-around is to drop support for rubbish (and often expensive) compilers. Might sound harsh, but that is the only way to put them under pressure. WIthout that C will never get out of the C90 depression. Re. stack size: is that different from fixed-size arrays or other variables or recursion? Sorry, but that is no argument against VLAs, but automatic variables in general (which you hopefully agree is pretty nonsense). Btw. the C standard does not mandate using a stack, you can very well allocate automatic variables using dynamic memory allocation. And the size is not compiler-specific
1

If you want something that is C89 compliant and doesn't use too much memory, there is a third option which is to allocate memory dynamically:

int n, i;
printf("Number of elements: ");
scanf("%d", &n);
int *myArray = malloc(sizeof(int)*n);   // allocate space for n ints
if (myArray == NULL) {
    perror("malloc failed");
    exit(1);
}
for(i = 0; i < n; i++)
    myArray[i] = 0;

Just be sure to call free on the allocated memory when you're done with it.

4 Comments

@dbush I always use pointers and malloc whenever I need to change the size dinamically, in this case I don't. When using MinGW with the c89 compiler flag it works the first way. Why should I use this instead? (what are the "benefits")
@Sheldon Using dynamic allocation is more portable. However if your compiler supports variable length arrays and you don't plan on migrating it, it has the advantage of not having to worry about freeing memory that's been allocated.
@KevinDTimm: calloc zeroes all bits. That is identical with the value 0 for integers only. Fine here, but not true for floating point or pointers. (It differs from default initialisers in this aspect, btw.) Just let the compiler figure out how to optimise that, A good compiler might use memset/memclr or even collapse both part into calloc. if that works.
@Olaf - OP has declared an array of int, I'm solving his problem, not the problem of others. If he wanted a solution to a generic problem, I assume he would have asked.