Search code examples
c++exceptionstack-overflow

Stack overflow exception before entering main()


when compiling (and executing) this c++ -code with vs2010, I get a stack overflow exception just before it could even write a glimpse of "Start" to the console.

All the header-files that I use are included in stdafx.h, but that's obviously not the problem here (same problem when including the header-files directly).

Stack trace is the following:

>   msvcr100d.dll!__set_flsgetvalue()  Zeile 145 + 0xc Bytes    C
    msvcr100d.dll!_getptd_noexit()  Zeile 500   C
    msvcr100d.dll!_getptd()  Zeile 523 + 0x5 Bytes  C
    msvcr100d.dll!_LocaleUpdate::_LocaleUpdate(localeinfo_struct * plocinfo)  Zeile 243 + 0x5 Bytes C++
    003efe3c()  
    TerrainGenerator.exe!pre_cpp_init()  Zeile 298 + 0x21 Bytes C

Any help would be greatly appreciated, I'm an absolute beginner in c++, as you may see in the code-style, I tried exactly EVERYTHING to get rid of this annoying problem, such as not even declaring ONE additional function and so on... Please help me, and don't hesitate to ask if you need additional info. Thanks in advance.

#include "stdafx.h"

int main(int argc, char* argv[])
{
    puts("Start");

    const int res = 4096;
    srand(time(NULL));

    uint16_t data[(res+1)*(res+1)];

    uint16_t variance = 2000;
    int seed = 1337;

    data[0] = ((seed>>1)+(int)(rand()/(RAND_MAX*(seed+(seed>>1)))));
    data[res] = ((seed>>1)+(int)(rand()/(RAND_MAX*(seed+(seed>>1)))));
    data[res*res] = ((seed>>1)+(int)(rand()/(RAND_MAX*(seed+(seed>>1)))));
    data[res*(res+1)] = ((seed>>1)+(int)(rand()/(RAND_MAX*(seed+(seed>>1)))));

    int count = 0;
    for(int size=res;size>=1;size=size>>1,variance=variance>>1)
    {
        count++;
        for(int x=size;x<res;x+=size<<1) 
        {
            for(int y=size;y<res;y+=size<<1) 
            {
                data[x*res+y] = data[(x-size)*res+(y-size)] + data[(x-size)*res+(y+size)] + data[(x+size)*res+(y-size)] + data[(x+size)*res+(y+size)];
                data[x*res+y] /= 4;
                data[x*res+y] += (variance>data[x*res+y])?(-(data[x*res+y]^2/variance)+(int)(rand()/(RAND_MAX*(data[x*res+y]^2/variance)))):(-variance+(int)(rand()/(RAND_MAX*variance*2)));
            }
        }

        for(int x=0;x<res;x+=size)
        {
            for(int y=0;y<res;y+=size)
            {
                if(x!=res-1)
                {
                    data[(x+(size>>1))*res+y] = data[x*res+y] + data[(x+size)*res+y] + ((y!=res-1)?data[(x+(size>>1))*res+(y+(size>>1))]:0) + ((y!=0)?data[(x+(size>>1))*res+(y-(size>>1))]:0);
                    data[(x+(size>>1))*res+y] /= (y!=res-1&&y!=0)?4:3;
                    data[(x+(size>>1))*res+y] += (variance>data[(x+(size>>1))*res+y])?((-(data[(x+(size>>1))*res+y]^2/variance)+(int)(rand()/(RAND_MAX*(data[(x+(size>>1))*res+y]^2/variance))))):(-variance+(int)(rand()/(RAND_MAX*variance*2)));
                }
                if(y!=res-1)
                {
                    data[x*res+(y+(size>>1))] = data[x*res+y] + data[x*res+(y+size)] + ((x!=res-1)?data[(x+(size>>1))*res+(y+(size>>1))]:0) + ((x!=0)?data[(x-(size>>1))*res+(y+(size>>1))]:0);
                    data[x*res+(y+(size>>1))] /= (x!=res-1&&x!=0)?4:3;
                    data[x*res+(y+(size>>1))] += (variance>data[x*res+(y+(size>>1))])?((-(data[x*res+(y+(size>>1))]^2/variance)+(int)(rand()/(RAND_MAX*(data[x*res+(y+(size>>1))]^2/variance))))):(-variance+(int)(rand()/(RAND_MAX*variance*2)));
                }
            }
        }
    }

    size_t Count = res*res;
    uint16_t* Block = data;
    char* Path = "export.raw";

    if(!Block) return false;
    FILE * filePointer = NULL;
    errno_t error = fopen_s(&filePointer, Path, "wb");
    if(error) return false;
    fwrite(Block, sizeof(uint16_t), Count, filePointer);
    fclose(filePointer);
    return true;

    return 0;
}

Solution

  • The problem is

    uint16_t data[(res+1)*(res+1)]; 
    

    it is a local array of 16 MB+ that is too big to fit in the stack (usually 1 MB) - you have to create it in the heap with a new statement:

    uint16_t* data = new uint16_t[(res+1)*(res+1)]; 
    

    and then remember to de-allocate it with a delete statement when you don't need it any more:

    delete[] data;