1

When is it better to instantiate a variable length array with calloc vs. "normal" array declaration in C?

Consider the 'array declaration' approach:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
 int n = atoi(argv[1]);
 int x[n];
 for(int i = 1; i < n; i++){
 x[i] = i;
 printf("%i", x[i]);
 printf("\n");
 }
 return 0;
}

vs. the calloc approach:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
 int n = atoi(argv[1]);
 int * x = (int*) calloc(n, sizeof(int));
 for(int i = 1; i < n; i++){
 x[i] = i;
 printf("%i", x[i]);
 printf("\n");
 }
 return 0;
}

Should you always use one or the other? Is one faster than the other (e.g. bc of stack vs heap allocation)? Is one a lot riskier than the other?

Vlad from Moscow
313k27 gold badges204 silver badges358 bronze badges
asked Jan 31, 2022 at 19:50
12
  • 4
    VLAs are deprecated by some reputable folks like Linus Torvalds. And for a reason - these are allocated on stack uncontrollably - that is, C has no mechanisms of detecting if it is overflowing the stack, unlike with the dynamic allocation (well, in your code you are not checking it as well, but you could). Commented Jan 31, 2022 at 19:54
  • 2
    Non-compile-time-deterministic automatic storage allocation should be avoided where at all possible (and it is almost always possible). Commented Jan 31, 2022 at 20:00
  • Frankly, I'd discourage you from using VLAs unless you were REALLY sure they're "ideal" for YOUR PARTICULAR USE CASE. Here's some useful discussion: stackoverflow.com/questions/22530363/…. I'd prefer: 1) declaring a fixed-size array, 2) using malloc(). Commented Jan 31, 2022 at 20:04
  • 1
    @EugeneSh., Linus is influential, but he does not have the power or authority to deprecate any feature of the C language. He can dislike them, discourage their use, refuse to accept them in the Linux kernel, and various other things, but "deprecating" features is something that only the standard committee can do. Commented Jan 31, 2022 at 20:05
  • 1
    @i486 there is so much more to VLA than stack allocated arrays though. The VLA typesystem is what's great about it. One can for example now easily allocate a dynamic multi dimensional array with one malloc call. I agree with you that one should avoid vla arrays on the stack, but we should embrace the other benefits it brings. Commented Jan 31, 2022 at 20:48

5 Answers 5

5
int x[n];

Automatic storage duration objects including VLAs are (by most modern implementations) allocated on the stack. There are some problems with the larger objects if they are allocated on the stack (three most important ones):

  1. There is no allocation control unless your program fails when you overflow the stack
  2. Stack is usually much much smaller than the heap. So the size of the array is limited
  3. The lifetime of the array is limited to the lifetime of the enclosing block. You can't return the reference to this array on the function return.
answered Jan 31, 2022 at 20:09
Sign up to request clarification or add additional context in comments.

Comments

2

the huge difference is that in the first example the array only exist for the life of the containing function but in the second case it lives on until its released.

In your example there is only the main function so the difference doesnt matter, but in real applications it matters a lot.

Second there is a limit to how large the first one can be since its allocated on the stack which is a limited resource. (Try it, make the array 1 million elements). The second case is limited only by the size of the heap, which is usually much much larger

answered Jan 31, 2022 at 19:57

Comments

0

Ask these two questions "Will my array size fit in the stack ?" and "for how long do i need this array (program or function life time)?".

Statically allocated arrays exist for the life time of the function. when return, the function stack (and any variables declared local to that function including your array) are destroyed, and any attempt to access them gives an undefined behavior.

However, if you do need to return a pointer to your array so that the values you store are available back in the calling function, then you do need to dynamically allocate it, When you dynamically allocate memory with calloc the lifetime extends from the time the memory is allocated, until it is deallocated.

Keep in mind that statically allocated memory are faster and more efficient than a dynamically allocated one so if you don't really need it don't be fancy.

answered Jan 31, 2022 at 20:10

Comments

0

Variable length arrays is conditionally supported by implementation.

If there is defined the macro name __STDC_NO_VLA__ then integer constant 1, intended to indicate that the implementation does not support variable length arrays or variably modified types.

Another problem is that the stack memory usually is much less than the memory used for dynamic memory allocation.

The size of a variable length array can be automatically changed then the control reaches anew the declaration of the array.

Variable length arrays have automatic storage duration and block scopes. So they are alive in block scopes where they are defined.

A dynamically allocated array can be resized using the function realloc preserving current values of its elements and you can explicitly control situations in the program when there is no enough space for a dynamically allocated array.

answered Jan 31, 2022 at 20:40

Comments

0

Generally speaking, only truly safe use of variable length arrays is for local typedef of multi-dimensional arrays. Anything else is dubious. Something like:

void *buf = calloc(a*b, sizeof(int));
typedef int Int2d[a][b];
Int2D *array2d = buf;
(*array2d)[y][x] = 42;

So use the calloc version. Only if you have a known small size, use VLA directly. And yes, that is a bit of a contradiction.

answered Jan 31, 2022 at 22:09

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.