4

When I define

void tfooo(){
int arr[SOME_LARGE_NUMBER];
// some code here
}

I am getting stack overflow, but when I add the static keyword

void tfooo(){
static int arr[SOME_LARGE_NUMBER];
// some code here
}

everything is fine.

What is the difference? Isn’t static arrays as opposed to dynamic arrays always defined on the stack?

Benny K
  • 1,957
  • 18
  • 33
  • 1
    You might find this helpful: https://stackoverflow.com/questions/93039/where-are-static-variables-stored-in-c-c – StaticBeagle May 28 '18 at 22:31
  • @DevSolar Was asking from c perspective. Also I am aware of that both examples are not dynamic allocation but static. The Q is why am I getting stack overflow only in the first example – Benny K May 28 '18 at 22:33
  • Possible duplicate of [Why declare a variable or function static in C?](https://stackoverflow.com/questions/1665250/why-declare-a-variable-or-function-static-in-c) – Bo Persson May 28 '18 at 22:34
  • 1
    Because the static array -- which outlives the current function invocation -- is allocated in the binary itself (ELF: .data / .bss section). So there is no stack involved. – DevSolar May 28 '18 at 22:42
  • "as opposed to dynamic arrays"? There are no dynamic arrays in your question. The first array is *automatic*. And yes, *automatic* arrays are typically stored on the stack. – AnT stands with Russia May 28 '18 at 22:53
  • @DevSolar inside a function , `static` does not mean "static linkage". Static variables inside functions have static storage duration, and *no linkage*. – M.M May 28 '18 at 22:53
  • @BennyK please clarify whether or not this code is inside a function – M.M May 28 '18 at 22:56
  • @M.M this code is definitely inside a function – Benny K May 29 '18 at 03:33
  • It would be good to edit your question to say that – M.M May 29 '18 at 03:33
  • @DevSolar: I think there's some confusion about the meaning of "dynamic". C doesn't use that term. C has "variable length arrays" (VLAs) whose length is determined at run time. An array (or any other object) with *automatic storage duration* has memory allocated for it at run time, on entry to the enclosing block. An object with *static storage duration* has memory allocated at program startup and deallocated only when the program terminates. (All static objects have fixed size, but automatic objects may have either fixed or "dynamic" size.) – Keith Thompson May 29 '18 at 23:27

2 Answers2

2

It is often the case that an object declared automatic is allocated on the stack (which is relatively small), whereas an object declared static is allocated elsewhere.

Notice, this depends on your machine and on your compiler.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
  • The "depends on your machine and compiler" is the part that should be emphasized. The [C11 Standard - 6.2.4 Storage durations of objects](http://port70.net/~nsz/c/c11/n1570.html#6.2.4) speaks only to the time when an object can be validly accessed, not where it is allocated. – David C. Rankin May 29 '18 at 04:11
1

I am generating the assembler code for the static version and non static version, and the only difference is that into the static version the variable does not exist. I think it has been removed because it is not used into my test.

Are you using the variable into the test are you doing? Maybe the optimiser has removed the variable into the static version.

I am using gcc. To build the assembler code, pass the -S argument:

gcc -S main.c

And this is the test code used for the non static version:

#define SOME_LARGE_NUMBER (100000000000000000)

int arr[SOME_LARGE_NUMBER];

int main(const int argc, const char* argv[]) {
    return 0;
}

And this for the static version:

#define SOME_LARGE_NUMBER (100000000000000000)

static int arr[SOME_LARGE_NUMBER];

int main(const int argc, const char* argv[]) {
    return 0;
}

This is the difference I got:

$ diff main.static.s main.nostatic.s 
23a24
>   .comm   _arr,400000000000000000,4 ## @arr

For the information you are providing this is what I can get. Could you paste more details about your code?


EDIT: Into the image attached we can see the memory layout for a windows application. When we use the static modifier into a function, it is stored into the .data segment instead of the stack of the program, because of that you don't get the stack overflow. In compiling time, the size of the array is known, so that, the binary image store enough space for the data. What is the size of your EXE file in both versions? If I am not mistake the EXE file size for the static version will be much bigger than the no static version. I suppose that the size of the array is reserved into the data segment when the binary is loaded. However, when using the no static version, it depends on how much memory is set up the stack. You can modify this size using the flag "/F" when compiling from the command line (see this link https://msdn.microsoft.com/en-us/library/tdkhxaks.aspx). I don't have a VM with windows to double check.

enter image description here

In overview, your static variable is not stored into the stack, because of that you don't get a stack overflow when using the static version.

  • I think they are talking about `arr` being defined inside a function – M.M May 28 '18 at 22:55
  • I don't know, the code I see is only the declaration and no more information. I have replayed the stack overflow with this code into my machine (x86_64 architecture). It is the only thing I can say. –  May 28 '18 at 22:57
  • @Alejandro Visiedo First,my code is inside a function . Second, I am using visual studio 2015 on x64 machine – Benny K May 29 '18 at 03:37