6

I'm using VS 2010.
When I run this program in the Debug mode it throws Stack overflow exception and shows a breakline in the file chkstk.asm at line 99.
But when I run it in the Release mode it's OK.
Also if I decrease the size of one of the arrays to 10000 it works well in Debug. What is the reason?

#include <iostream>

using namespace std;
int main()
{
    char w[1000001], temp[1000001];
    cout<<"Why?"<<endl;
    return 0;
}
ildjarn
  • 62,044
  • 9
  • 127
  • 211
Temak
  • 2,929
  • 36
  • 49
  • 3
    What optimisations do you have enabled in release mode? There's a good chance that the compiler is just removing the arrays. – San Jacinto May 10 '12 at 21:41
  • possible duplicate of [Stack overflow when debugging but not in release](http://stackoverflow.com/questions/5670904/stack-overflow-when-debugging-but-not-in-release) – Bo Persson May 10 '12 at 21:49
  • Are you asking "What is the reason for the overflow?" Or "What is the reason that the behavior changes in different build modes?" Or something else? – Robᵩ May 10 '12 at 21:52
  • as the probably solution i have found #pragma comment(linker, "/STACK:1000000000") – Temak May 10 '12 at 21:53
  • @Enor : You really do not want your stack to be 1GB -- that's more than a bit overkill. – ildjarn May 10 '12 at 22:34
  • 2
    It's crashing in DEBUG mode because you have allocated too many variables on the stack. It's not crashing in RELEASE mode because the compiler recognized that you aren't even using w and temp and is optimizing them into non-existence. If they don't exist, they don't take up space on the stack, and they can't cause it to overflow. – Joseph Willcoxson May 11 '12 at 02:12

4 Answers4

12

Because the stack is pretty small, approx 1MB on most systems, you're overflowing it with your large buffers. To fix that, just allocate on the heap like this:

#include <iostream>

using namespace std;
int main()
{
    char* w = new char[1000001];
    char* temp = new char[1000001];
    cout<<"Why?"<<endl;
    delete[] w;
    delete[] temp; 
    return 0;
}
Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
5

The stack is pretty small (~1MB). You're filling it up with the huge number of elements in those arrays.

If you need more space, try allocating on the heap (which pointers do).

A good way to implement this is with vectors, which internally store things on the heap:

std::vector<char> w (1000001);
std::vector<char> temp (1000001);
chris
  • 60,560
  • 13
  • 143
  • 205
5

You are allocating too much stuff on the stack; probably in debug mode the stack is more occupied because of the various safety checks, or is intentionally smaller to help you detect such problems earlier. Anyhow, making the arrays a little bigger will trigger a stack overflow even in release mode (unless the compiler optimizes them out altogether).

The root of the problem here is that you shouldn't allocate big stuff on the stack, which is quite limited in size (1 MB by default on Windows with VC++) and should be used only for small buffers/objects. If you need to do big allocations, do them on the heap (with new/malloc), preferably using smart pointers to avoid memory leaks.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
4

Arrays in the automatic storage are allocated on the stack. Stack space is limited. When the space on the stack is insufficient to allocate automatic variables, stack overflow exception occurs.

If you need arrays that big, use static or dynamic allocation instead.

For static allocation, move declarations to outside main().

For dynamic allocation, use the code below:

char *w = new char[1000001], *temp = new char[1000001];
// Work with w and temp as usual, then
delete[] w;
delete[] temp;

Finally, consider using standard containers instead of plain arrays: std::array is a better array if you do not need resizing (it is allocated on the stack, and will not solve this problem); std::string is also a good candidate to replace char arrays.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 2
    I don't think `std::array` will solve his problem. It will *still* allocate the data on the stack. Try `std::vector`. – Robᵩ May 10 '12 at 21:50
  • @Robᵩ You're right, it wouldn't! I mentioned `std::array` as a replacement for plain arrays, not as a way to solve this particular problem. I can see how this part of the answer could be misleading, so I edited it for clarity. Thanks! – Sergey Kalinichenko May 10 '12 at 22:00