Why do I need to use dynamic memory allocation when I can achieve the same from static?

Viewed 463

Let me take an example to explain my problem,

Case I

#include<iostream>
using namespace std;
int main(){
   int n;
   cin>>n;
   int a[n];
   for(int i=0;i<n;i++)
       cin>>a[i];
}

Case II

#include<iostream>
using namespace std;
int main(){
   int n;
   cin>>n;
   int *a = new int[n];
   for(int i=0;i<n;i++)
       cin>>a[i];
}

Correct me if I am wrong, to my understanding, Case I falls under static memory allocation domain and Case II falls under dynamic memory allocation domain. So if I am able to achieve the same functionality by static memory allocation, why use dynamic.

In both the above cases, I am able to achieve the same functionality, but why is Case I considered bad and Case II the correct way.

The only difference in both the codes is line number 6.

3 Answers

Case I falls under static memory allocation domain and Case II falls under dynamic memory allocation domain.

This assumption is wrong. The non-standard feature you are using with such a snippet;

int n;

// determin n at runtime ...

int a[n];

is called VLA (variable length array) (see this thread for more details) and is a contentious way of hiding memory allocation (possibly on the stack, see @André's comment) and eventually clean-up behind a convenient syntax.

Note that without the non-standard VLA extension, you will not be able to use arrays from stack space when the maximum array dimension is not know at compile time. Working example:

#include <array>

constexpr std::size_t N = 42; // known at compile time

std::array<int, N> data; // allocated on the stack

The case 1 does not do a "static" memory allocation, rather it's memory allocation "on stack". It's a variable length array.

There are multiple reasons:

  • Variable length arrays is a compiler extension. They are not part of C++.

  • There is no error handling with variable length arrays. It's impossible to forward to the user any meaningful error message and it's very hard to debug such programs. Typically the process will just show an unfriendly "segmentation fault" error message.

  • The maximum allocated memory will be only very, very small and will depend on other parts of the code (making debugging really hard). Mostly linux has stack limit set to 8Mb. Allocating more will not error, but rather the process will receive a segmentation fault signal when writing to a memory location past that threshold. You can always set a bigger stack limit for you process.

  • The memory has to be freed at the end of the block. It's not possible to return such memory from a function and use it outside of it's scope, which makes it useless for most applications where dynamic memory is used.

As @lubgr explained, it is not possible to allocate static memory(in the stack) that is not determined at the compile time. so if you want to determine memory at runtime, you should use dynamic memory allocation(Heap).

Furthermore, as @Jeff Hill explained in Heap vs Stack post, Heap size is dynamic at runtime, while stack size is static(So even if it was possible to allocate runtime variable memory in Stack, then sometimes your application faced Stack overflow).

Another different is speed; the Stack is faster than the Heap(because of their access pattern)

Related