3

I am getting an introduction to dynamic memory allocation, and I learned that a dynamic array ( the one like int *p = new int[n] \\ where n is the user input describing the number of elements is used when you do not know how many elements the user requires/ declaring an array of a size that the user wants. However, instead of doing that, why can't we declare a static array like this:

int n;
    cout << "Enter the size : " <<endl;
    cin>>n;
    int a[n];

What is the advantage of dynamic arrays in this case then? I am not understanding this concept.

Edit : Thanks for your answers. Some users responded by saying that declaring an array by typing a[n] is not allowed. However, why does my program run fine when I type the following code :

int main(){
    int n;
    cout << "Enter the size : " <<endl;
    cin>>n;
    int a[n];
    cout << "Enter your numbers : " <<endl;
    for (int i=0;i<=n;i++){
        cin>>a[i];
    }
    for (int i=0;i<=n;i++){
        cout<<a[i]<<endl;
    }
}
Anon 123
  • 73
  • 5

3 Answers3

3

Now, people have already stated that int a[n] is not valid c++. But Perhaps I could help you with the answer you're looking for.

What is the advantage of dynamic arrays in this case then?

The syntax int a[n] is called a VLA (Variable Length Array). These are illegal in C++ but allowed in C. So let's focus on the technical differences, or rather disadvantages of VLAs.

Let's get the obvious thing out of the way first. C89 and before did not have VLA and hence dynamic allocation was the only way for allocating variable length memory.

One more thing, static arrays and even VLAs are allocated on the stack (although this is implementation defined, but more often than not, it will be on the stack). Whereas dynamic arrays are allocated on the heap. For more information on the stack and the heap, read this

Now, VLAs are banned in C++ for a very good reason. VLAs can cause all sorts of undefined behaviours and should always be avoided unless you know exactly what you're doing. And by "you know exactly what you're doing", I mean you know that the size argument of that VLA will not overflow the stack.

Suppose VLAs were allowed in C++, this line in your code-

cin>>n;
int a[n];

What if the user enters a massive n, way more than the stack size? That's a guaranteed stack overflow. Notice the problem? As compared to the heap, the stack is very tiny. This is also explained here and also here

And this is the primary reason VLAs should be avoided at all costs. Though VLAs actually come with much more boom than the aforementioned. Infact I always keep a list of UBs associated with VLAs handy, there just is that many problems.

So going back to my point of

[VLAs] should always be avoided unless you know exactly what you're doing

Honestly, you should never use VLAs, and you really can't because that's not even standard C++. But stack allocation is often faster than heap allocation. Though not for reasons one might consider obvious. Read this. So sometimes, if you're on C (not C++), the only times using a VLA is safe is when you know the max size of n in int a[n] will not overflow the stack and the declaration of the VLA is at the top of the scope you are currently declaring it at. The creator of alloca (which used to be the only way to use VLA prior to c99) seems to agree.

Excerpt from here-

You may use alloca() in the form of:

pointer_variable = alloca(expression);

as an expression statement in the outermost block of a function.

Oh and just to answer your edit:

Thanks for your answers. Some users responded by saying that declaring an array by typing a[n] is not allowed. However, why does my program run fine when I type the following code :

It's because your compiler allows it. But remember, the standard does not. So these kinds of things can give birth to the good ol' "It worked on my machine!"

Community
  • 1
  • 1
Chase
  • 5,315
  • 2
  • 15
  • 41
2
int a[n];

This line declares a variable-length array, but that's not part of C++. Some compilers implement it as an extension, but it's not actually C++ at that point. It would be a specific compiler's dialect of C++.

So, this isn't even an option (if you want your code to be portable).

The standard advice is to use std::vector<int> instead of managing your own memory, so I would suggest doing that. (Of course, there is nothing wrong with exercises to help you understand how to do proper memory management.)

cdhowie
  • 158,093
  • 24
  • 286
  • 300
2

However, instead of doing that, why can't we declare a static array like this:

Because the language rules say so. In C++, the size of all variables must be known at compile time.

Note that if you declare an array like that (if the size was known at compile time), the array would have automatic storage, not static storage.

What is the advantage of dynamic arrays in this case then?

The advantage is that the size of a dynamic array doesn't need to be known at compile time.

Furthermore, the amount of automatic storage is very limited typically, while dynamic storage is not. Creating large arrays with automatic storage has high chance of causing a stack overflow.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • but when I write the following code, the program works fine. Why is it so?int main(){ int n; cout << "Enter the size : " <>n; int a[n]; cout << "Enter your numbers : " <>a[i]; } for (int i=0;i<=n;i++){ cout< – Anon 123 May 30 '20 at 19:05
  • 1
    @Anon123 The program is ill-formed. When an ill-formed program compiles compiles then typically either 1. The compiler implements a language extension or 2. The compiler is broken. In this case, it is 1. If the compiler does not issue a diagnostic message, then it doesn't conform to the C++ standard. – eerorika May 30 '20 at 19:06
  • Sometimes programs that work fine are not legal C++. For another example, look at this from your code above `for (int i=0;i<=n;i++)` that should be `for (int i=0;i – john May 30 '20 at 19:55