2

During some memory tests I did I got a segfault from the following program:

#include <string>
#include <iostream>
using namespace std;

int main()
{
    cout << "Beginning Test" << endl;
    const int N = 2000000;  
    string sArray[N];
    return 0;
}

Since I got the segfault before "Beginning Test" was printed, I ran it in GDB and checked the backtrace and the only thing I got was:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004008c5 in main () at Main.cxx:11
11 string sArray[N];
(gdb) bt
#0 0x00000000004008c5 in main () at Main.cxx:11

The weirdest thing for me is that if I set N to 1000000 (1M) instead of 2000000 (2M) I don't get the segfault.

Any clue to what the problem might be?

I'm using Linux Red-Hat 2.6.18 and g++ (GCC) 4.1.2.

Thanks!

infokiller
  • 3,086
  • 1
  • 21
  • 28

5 Answers5

16

Stack overflow...

You did it on purpose, didn't you?

fge
  • 119,121
  • 33
  • 254
  • 329
  • lol, but why is the stack so small? sizeof(string)=8, so 2,000,000*8 = 16MB. Which means that the stack size is bigger than 8MB and smaller than 16MB but its seems really small to me (I have 32GB ram on this machine) – infokiller Dec 29 '11 at 13:04
  • @JohnnyW The stack is small but the memory available to a program (data & heap) is quite large. – cnicutar Dec 29 '11 at 13:07
  • Yes I'm aware of that, but why is the stack size so limited? – infokiller Dec 29 '11 at 13:19
  • 2
    Because we usually do not need a lot of stack, so it is better not to waste part of the address range for stack space when it is not going to be needed. Do not forget that every thread needs its own stack, so at any given moment there are lots of stacks on your machine. We do not need a lot of stack because we never allocate large objects in it. If we did, then there would never be any amount of stack that we would find large enough. We just use the heap for large objects, which we have to use anyway, because there are things that cannot be done with the stack. – Mike Nakis Dec 29 '11 at 14:17
  • 1
    The stack is there to hold two main things: automatic variables (which your huge array is) and function arguments. When a function calls another, the caller's arguments are "pushed" onto the stack, along with the callee's arguments, and the latter can also allocate automatic variables. When the callee is done, its arguments and automatic storage are "popped" and the caller resumes. If the stack space were not limited, well... Think about this: `void f(int i) { f(i); }`. – fge Dec 29 '11 at 19:12
  • @infokiller 8 MB is not small. I regularly program for systems with <= 8 KiB of RAM. – 12431234123412341234123 Jan 19 '21 at 16:42
6

You are overflowing the stack and for some reason the output doesn't get flushed. 2M strings is quite a lot of memory. Try using the heap instead of the stack.

Best of all, use vector instead of an array and stop worrying about manual allocation.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
1
string sArray[N];

Is probably using up all the stack memory which causes it to segfault.

ronag
  • 49,529
  • 25
  • 126
  • 221
1

What happens is that sArray is local to your main method, so it is going to be allocated on the stack. But the stack is not enough to hold 2000000 elements, so it blows up.

Now, the compiler attempts to allocate sArray at the very beginning of the function, (conceptually, at the '{',) so that's why the stack overflow occurs before the "Beginning Test" is output.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
0

You just got stack overflow. If you want to allocate a big arrays on the stack you need to change a stack size. Look for instruction here Increase stack size in Linux with setrlimit

Community
  • 1
  • 1
Oleksandr Pryimak
  • 1,561
  • 9
  • 11