简体   繁体   中英

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

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];

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 .

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.

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM