Dynamically allocating array with the [] operator instead of using malloc?
Asked Answered
F

5

7

I am sure this has been asked a million times but I couldn't find an answer that explained it. I have been told to never do this but I haven't really understood why. Why doesn't something like this count as dynamically allocating memory and why is it that bad?

int a;
scanf("%d",&a);
int arr[a];
Femme answered 16/4, 2021 at 13:9 Comment(1)
this isn't the [] operator, it's called a variable-length arrayHuzzah
C
4

This is not dynamic allocation but a variable length array.

The lifetime of such an array is its enclosing scope, just like an array with a fixed size, so you don't need to worry about deallocation. These arrays typically reside on the stack, so the size of the stack does put limitations on how big a VLA (or any array) can be.

If you find that a VLA is too big for the stack, you can always fall back to using malloc.

Cubital answered 16/4, 2021 at 13:13 Comment(2)
Thanks for answering, so this isnt necessarily bad just not very useful most of the time?Femme
@Femme It's useful if the array isn't huge, i.e. 1MB or more in size.Cubital
D
3

Dynamically allocating array with the [] operator instead of using malloc?

The [] here is used to define an array. [] here, is not an operator.

int arr[a];

I have been told to never do this but i havent really understood why.

This mantra applies to many things in C (and life), do not use until you understand how to use it.

Why doesnt something like this count as dynamically allocating memory

It is dynamically allocating memory allocation, but usually uses a different memory pool and has a different lifetime than via malloc().

... and why is it that bad?

int arr[a]; is a variable length array (VLA) and has the following issues:

  • Not always available. VLAs supported in C99 and often, but not always, in later versions. Research __STDC_NO_VLA__.

  • With int a, code is undefined behavior (UB) when a <= 0.

  • When a is too large, there is no standard mechanism to detect insufficient memory.

VLA better used in controlled smaller size cases.

Dollar answered 16/4, 2021 at 14:5 Comment(1)
Small explanation to the "different memory pool": malloc allocates new memory on the heap, where int arr[a] puts the array on the stack (where your local variables are).Maziar
S
1

First of all, let me tell you that this is called variable length array, and it's an optional feature. Better not to rely on this feature (or compiler support).

On the other hand, allocator functions (malloc(), free() and family) are standard compliant and any conforming compiler / library will support these functions.

That said, the differences are mentioned in other answers, primary differences are with scope and portability.

Scheel answered 16/4, 2021 at 13:13 Comment(4)
Thanks for the answer, so in some compilers this wont even compile?Femme
@Femme Yes, some compilers may not have support for VLAs. Not entirely sure but IIRC, Microsoft compilers did not support VLAs.Scheel
Many conforming freestanding compilers support VLA but not malloc, which is also an optional feature for freestanding implementations... so we should avoid most of the standard C lib then?Pauperize
@Pauperize That depends on your target environment. If you don't need them , don't use them. We include the standard header files, while we could have just added the required function prototype by hand.Scheel
S
1

Why doesnt something like this count as dynamically allocating memory

That the size of the object is determined at runtime is not sufficient for dynamic allocation. Dynamic allocation requires direct or indirect use of one of the functions that specifically performs dynamic memory allocation, with malloc, calloc, and realloc being the main examples. Your example ...

int arr[a];

... does not do this, so the object is not dynamically allocated. You arr is a more-or-less ordinary local variable with variable-length array type.

Semantically, dynamically allocated objects have "allocated" storage duration, which means that they exist and retain their last-stored value until explicitly deallocated. Your arr instead has "automatic" storage duration, which means that it ceases to exist when execution of its innermost containing block terminates.

and why is it that bad?

Opinions vary. VLAs were a required feature in C99, but support was made optional in C11. If you use VLAs in your code, then, you limit its portability. C++ does not support them (or at least did not -- I understand that they are now coming to C++, too, and maybe they have already arrived), which may be an issue for some.

However, the main risk cited is that the usual and natural implementation of VLAs is to allocate them on the stack, and stack size is typically a lot more limited than heap space. In a naive example such as yours, it is easy to create a stack overflow, and this may depend on user input, thus making it both difficult to test and a potential security risk.

I do use VLAs in my code from time to time, but usually in ways that are not subject to the stack-busting risk described above. I generally look skeptically on admonitions to "never do that", but indeed I would never write the exact code you present for a production application.

September answered 16/4, 2021 at 13:26 Comment(0)
R
1

This is an example of a variable length array. Its lifetime is the same as any other auto variable (including fixed-length arrays), so memory for it will be released once you exit its enclosing scope.

Unlike fixed-length arrays, VLAs cannot be declared at file scope (outside of any function) or with the static keyword, nor can they be declared with an initializer. Because of how they are typically managed, they cannot be arbitrarily large. Despite the name, they cannot be resized once they are defined - the "variable" in variable length only means that their size can be different each time they are defined.

VLAs are useful but limited. They're great when you need some temporary working storage that's local to a function and doesn't need to be too big (not much bigger than a megabyte or so).

They were only introduced in C99 and made optional in C11, so support for them may be a little spotty.

Respectability answered 16/4, 2021 at 14:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.