-2

I'm trying to code something in C on my mac, and I ran into a Segmentation Fault: 11. I've located the problem to be the declaration of a double array of 5 million elements. For instance, the following code gives a Segmentation Fault:

int main(){
    double vals[5000000];
    return 0;
}

My first question is, is 8*5000000 bytes = 40 MB too large? I also tried to run this on another machine (linux), which ran smoothly. So the second question is, what determines the memory available to the application? Does it have to do with the available RAM on the machine (my mac has 16 GB, the linux machine has 62 GB)? Or does it have something to do with the compiler options (I'm using gcc without any options on both machines, but different versions).

Edit: Okay, so I've changed the test code to the following because in the actual code the variable is not unused:

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

int main(){
   double vals[5000000];
   vals[0] = 500;

   printf("%lf\n",vals[0]);

   return 0;
}

Also, I compile without any options/optimizing: gcc test.c.

(I'm also wondering if the downvoter actually realized I'm asking more than "oh, why am I getting a segmentation fault?" like all the other questions out there.)

sodiumnitrate
  • 2,899
  • 6
  • 30
  • 49
  • 1
    It is more likely a system configuration, i.e. environment problem. Just be carefull with automatic variables. Also note that they are allocate – too honest for this site Dec 13 '15 at 03:29
  • 1
    see this link : http://www.cs.nyu.edu/exact/core/doc/stackOverflow.txt. I think that is exactly what you want – Chiron Dec 13 '15 at 03:31
  • 1
    @Chiron: The values for Linux and Solaris look strange. For Linux at least, they are normally exactly 8MiB, the text says it's exactly 20KiB less. And the max. stack size for Linux is the same as the default, but they can store more data for `PI`. – too honest for this site Dec 13 '15 at 03:36
  • According to @JWL s answer: did you check if the code really allocates the memory on the stack? The variable is actually not used, so why should any memory be allocated? What optimisation settings do you use? How does the assembler code look like? – too honest for this site Dec 13 '15 at 03:41
  • @olaf Ok, how can I check whether the code allocates memory on the stack? Sure, the variable is not used here, but I wrote this one to single out the problem in my main code, which does use the value. I don't use any options while compiling: `gcc test.c`. – sodiumnitrate Dec 13 '15 at 03:46
  • As I wrote. Just check the generated assembler code on both machines. But if your actual code **does** access the array, there is no actual need. (Note this is the reason to provide a [mvce]!). – too honest for this site Dec 13 '15 at 03:53
  • @olaf Ok, I didn't know whether the array is accessed made a difference. Again, sorry for the basic question, but what is the assembler code and how can I check it? – sodiumnitrate Dec 13 '15 at 03:55
  • @sodiumnitrate: Sorry, please understand SO is no tutorial site. Any good C book will explain how code is compiledand a program is built. And about more details, please do some research on your own. Wikipedia might be a good start. – too honest for this site Dec 13 '15 at 03:58
  • @olaf Alright, will do. Thank you for the help. – sodiumnitrate Dec 13 '15 at 03:59
  • Please provide the exact code you use. As given, the array still might be optimised out, thus explaining why one platform does not seem to have a problem. However, for practical reasons, you should assume the array is too large for an automatic variable. – too honest for this site Dec 13 '15 at 04:00

2 Answers2

5

Because you're creating that as an automatic variable, it will go on the stack. The stack size is not very large. A general rule of thumb is for any objects larger than a few KBs, always dynamically allocate them on the heap using malloc() (or new for C++).

Your program is crashing because the size of the stack grew larger than it was allowed to. That's known as a stack overflow and is usually seen when you have unbounded recursion.

The size of the stack is implementation defined, so it's very possible that the default stack size on Linux is larger than on OS X.

fuz
  • 88,405
  • 25
  • 200
  • 352
C0deH4cker
  • 3,959
  • 1
  • 24
  • 35
  • 2
    Not all local variables are allocated on the stack. If it was declared `static`, it still was a local variable, but placed in global storage. And there is no problem just defining a global variable (or said local `static`). – too honest for this site Dec 13 '15 at 03:30
  • @Olaf Of course, but I don't consider static local variables to truly be local variables, as they are global for all invocations of the function. The scope of that variable might be limited to the one function, but it lives on at a global scope and can be accessed by recursive calls or subsequent calls. So really static local variables are still global, but they can only be accessed by a single function. – C0deH4cker Dec 13 '15 at 03:44
  • 1
    "The scope of that variable might be limited to the one function, but it lives on at a global scope ..." is an oxymoron. Funny enough, I just had an argument about `global` meaning linkage/visibility or lifetime (I was for lifetime, but was outvoted). However, it still is a local, aka function/block scope variable as of the standard - _scope_ definitively means visibility, not lifetime. What you mean are _automatic_ variables (that's why the `auto` storage class specifier is called like that). Btw. the standard does not require to use a stack. – too honest for this site Dec 13 '15 at 04:08
  • I think I'm using the wrong terminology. I don't mean global as in globally visible but at a scope greater than a single function invocation. It is accessible from outside of the current function invocation, so it isn't only accessible locally. And yeah while the standard doesn't require a stack, I am not aware of a single machine where local variables aren't allocated on a stack. – C0deH4cker Dec 13 '15 at 04:32
  • @C0deH4cker The proper jargon is “automatic variable” for what you call “local variable but not statis.” – fuz Dec 13 '15 at 09:43
  • @C0deH4cker: _scope_ means visibility/accessibility. As I already wrote, you think about _storage duration_ (which is the term used in the standard for _lifetime_). These are different things. Actually the standard does not use _local_ or _global_, but only the [_scope_](http://port70.net/~nsz/c/c11/n1570.html#6.2.1), [_linkage_](http://port70.net/~nsz/c/c11/n1570.html#6.2.2) and [_storage duration_](http://port70.net/~nsz/c/c11/n1570.html#6.2.4). – too honest for this site Dec 13 '15 at 15:43
  • @C0deH4cker: Almost every modern compiler does allocate _automatic_ variables not only on the stack, but also e.g. in CPU registers. Also, was said, `static` local variables are not put onto the stack. As said, the C standard does not require a stack (or a heap); there are other techniques. There are very well architectures which don't even have a data-stack, e.g. PIC12..18 or HC08/S08. Please think about extending your field of vision. – too honest for this site Dec 13 '15 at 15:46
  • @Olaf Yes of course compilers will place automatic variables in registers at times, but live variables are placed on the stack by called functions that would overwrite those registers. So any recursive calls will place all live variables on the stack. And I've never heard of those architectures, but I would be surprised it they didn't tread some part of memory as a "stack" for function calls, at least for compiled C code. I'm not sure if you're playing devil's advocate or just trying to be overly pedantic, but this argument isn't useful. – C0deH4cker Dec 14 '15 at 05:23
  • @C0deH4cker: Well, I **do** know these architectures. And I have written myself some compilers (although not for C, but it's the principle), interpreters, etc. As I say,widen your horizon. Just because you cannot think it is possible, it does not mean it does not exist. So, do some research and get surprised! – too honest for this site Dec 14 '15 at 13:46
1

I guess the reason it works on the other machine is because the compiler has optimization for unused variables.

JWL
  • 111
  • 3