0

I am writing a program to get all the prime nos upto a number n(input).

Now in this program, I have used static storage allocation int arr[n+1] however my compiler doesn't know the value of n during compilation (n is provided by the user as input) and hence doesn't know how much space should be allocated.

Should one use dynamic storage allocation in this program?

int *arr=new int[n+1]

However, the program is running perfectly in both cases.

I just wanted to know why my program is running fine in case of static storage allocation even though n is unknown during compilation and the compiler doesn't know how much storage should be allocated.

void prime(int n) {
  int arr[n + 1]; // <=======

  for (int i = 0; i < n + 1; i++) {
    arr[i] = 1;
  }

  for (int i = 2; i <= n; i++) {
    for (int j = 2 * i, l = 0; j < n + 1; j = (2 + l) * i, l++) {
      arr[j] = 0;
    }
  }

  for (int i = 2; i < n + 1; i++) {
    if (arr[i] == 1) {
      cout << i << " ";
    }
  }
}

int main() {
  int n;
  cin >> n;
  prime(n);
}
t.niese
  • 39,256
  • 9
  • 74
  • 101
  • 2
    `int arr[n+1];` that's not static allocation. That's a VLA and should be avoided in most cases. I'd go with `std::vector` for that. – Guillaume Racicot Oct 29 '19 at 19:21
  • 1
    `int arr[n+1]` isn't allowed in c++ (n is not a compile time constant here). GCC allows it as an extension, but that's not supported by the language. So that sort of narrows down your question. – François Andrieux Oct 29 '19 at 19:22
  • 1
    VLAs are *not* part of standard C++. Unfortunately, some compilers accept them as extensions by default (luckily this can be disabled and the compilers *can* be told to be standard compliant - I'd advise doing so). Use `-std=c++17` and `-Wvla` for GCC for example. – Jesper Juhl Oct 29 '19 at 19:24
  • Whenever you are writing some text you should consider adding some new lines, which heavily increase readability. – t.niese Oct 29 '19 at 19:26
  • OP, you can also use `-pedantic-errors` to disable this extension and similar ones completely (i.e. making these compiler errors instead of just warnings as @JesperJuhl's answer does.) – walnut Oct 29 '19 at 19:27
  • For those wondering (I had to look it up) VLA is Variable Length Array. – Joseph Larson Oct 29 '19 at 19:29
  • @uneven_mark I *know*. Trust me, my compiler command lines are much more pedantic and enables way more warnings than this.. and, of course, warnings as errors. – Jesper Juhl Oct 29 '19 at 19:29
  • @JesperJuhl Sorry, I meant to address OP. But in any case I am wondering why you advised for just a warning, which learners often ignore anyway. – walnut Oct 29 '19 at 19:32
  • @uneven-mark with `-std=c++17` rather than the default `-std=gnu++17`, VLAs will be errors. But if they don't change the language standard, then `-Wvla` will at least give a warning.. And if you just ignore compiler warnings, well, then I can't help.. `-Werror` should (IMO) be enabled by default. – Jesper Juhl Oct 29 '19 at 19:37
  • @JesperJuhl GCC does not warn or error for VLAs with only `-std=c++17` and actually disables VLAs with `-pedantic-errors` no matter whether `-std=c++17` or `-std=gnu++17` is used: https://godbolt.org/z/3oxeIg – walnut Oct 29 '19 at 20:38

1 Answers1

0

This

void prime(int n) {
  int arr[n + 1]; // <=======

is not a static allocation. It is a dynamic stack allocation and it is known as variable length array. Which is not allowed by C++ even though all (most?) compilers do accept such code. For more information read here: Why aren't variable-length arrays part of the C++ standard?

Anyway the rule of thumb is: use dynamic heap allocation when (a) you require some object to live "long" time (i.e. longer then the function call itself) or (b) you need lots of memory or (c) you have variable length collection (even though there still are ways to dynamically allocate stack memory, e.g. alloca, I consider it a micro optimization and tricky to work with - avoid if possible).

Also you may want to utilize std::vector. It uses dynamic heap allocation under the hood as well but is generally safer than manual new/delete.

freakish
  • 54,167
  • 9
  • 132
  • 169
  • 1
    "even though all (most?) compilers do accept such code" - MSVC won't accept it. GCC and clang (unfortunately) accept it by default as an extension. But if you build in standard compliant mode (which you, IMHO, should) then they will reject it. – Jesper Juhl Oct 29 '19 at 19:34