0

I have an array populated with integers:

#include <stdio.h>

#define MAX 4000000

int main() {
  int primes[MAX + 1];

  // init array with all numbers
  for(int i = 1; i <= MAX; i++)
    primes[i] = i;

  return 0;
}

With 4 byte integers, it seems this should only use up 4M * 4 or 16 MB. But I'm getting a segmentation fault when I run this program. I don't understand why.

StevieD
  • 6,925
  • 2
  • 25
  • 45
  • 2
    Tip: Don't allocate large structures on the stack, use dynamic allocation (e.g. `malloc` or `calloc`). – tadman Mar 28 '20 at 01:19
  • I can't reproduce that here (macOS + clang), but it could be compiler dependent, or an artifact of your OS. – tadman Mar 28 '20 at 01:20
  • 2
    The cause of your problem is stated in the address bar of your browser, right in between the `https://` and the `.com`. Also in the upper left corner of this web page. :-) – Nate Eldredge Mar 28 '20 at 01:20
  • @tadman yeah, I'm on macos and clang as well. Weird. – StevieD Mar 28 '20 at 01:24
  • You should make minimal use of the stack in your program as the default is usually 8MB. Anything more and you get a literal *stack overflow*. `ulimit` limits apply. – tadman Mar 28 '20 at 01:25
  • OK, making this an extern variable by moving it outside main did the trick. Thanks @tadman – StevieD Mar 28 '20 at 01:26
  • That's not exactly a solution, either. Why not dynamically allocate it? – tadman Mar 28 '20 at 01:27
  • Weak compiler puts `int primes[MAX + 1];` on stack with limited space. – chux - Reinstate Monica Mar 28 '20 at 01:31
  • I haven't learned about malloc yet. These are just toy programs I'm writing to learn C so just interested in getting it working for now. – StevieD Mar 28 '20 at 01:32
  • @tadman using static allocation certainly is a solution – M.M Mar 28 '20 at 02:09
  • @M.M If by that you mean "just use global variables" then that's not really a solution so much as trading one anti-pattern for another. – tadman Mar 28 '20 at 19:39

1 Answers1

1

As with any structure too large to accommodate on the stack, the solution is to dynamically allocate:

#include <stdio.h>
#include <stdlib.h>

#define MAX 4000000

int main() {
  int* primes = calloc(MAX + 1, sizeof(int));

  // init array with all numbers
  for(int i = 1; i <= MAX; i++)
    primes[i] = i;

  free(primes);

  return 0;
}
tadman
  • 208,517
  • 23
  • 234
  • 262