C++ WINAPI Exception Unhandled Stack Overflow before reaching code

-3

I've put together a nice little terrain engine in direct x. I changed the width and height of the land from 256 to 512 and now when I run the debugger the program crashes in wWinMain. The Width and Height are const static unsigned int I should add that if I change the numbers back to 256 the program debugs fine without error. Only when changing these numbers does it throw a stack-overflow error.

Unhandled exception at 0x00007FF7065C9FB8 in TerrainEngine.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x00000022AA803000).

class Constants
{
public:
    // World rows and columns
    const static unsigned int WorldWidth = 256; //changing this to a number greater than
    const static unsigned int WorldHeight = 256; //256 causes stack overflow

When changing WorldWidth or WorldHeight to a number greater than 256 I get a stack overflow error at the very beginning of my code, so early that I'm unable to properly debug further to see what's going wrong.

enter image description here

void World::Initialize(Graphics & graphics)
{
    this->graphics = &graphics;

    ....

    // Setup Perlin Noise
    PerlinNoise perlinNoise = PerlinNoise(237);

    for (unsigned int y = 0; y < Constants::WorldHeight; y++)
    {
        for (unsigned int x = 0; x < Constants::WorldWidth; x++)
        {
            double xx = (double)x / ((double)Constants::WorldWidth);
            double yy = (double)y / ((double)Constants::WorldHeight);

            //define in header as std::array<std::array<float, Constants::WorldWidth>, Constants::WorldHeight> heightmap;
            heightmap[x][y] = perlinNoise.noise(xx, yy, 1);
            tileManager.SetTile(x, y, Math::GetType(heightmap[x][y]));
        }
    }
}


void World::Update(Keyboard& keyboard)
{
    // The only other time WorldWidth is referenced
    //posX is public signed int
    posX = Math::Clamp(
        posX,
        Constants::WorldWidth - Constants::RenderWidth,
        Constants::RenderWidth);

Can anyone explain what's happening, cause I'm unable to debug past the first curly brace which leads to the wWinMain method, and I don't understand how changing these two values can cause the program to throw this error.

World is declared as raw, ordinary private member in the Game header file.

World world;

It has one constructor that is empty.

c++
winapi
memory
directx
stack-overflow
asked on Stack Overflow Mar 19, 2019 by Anthony • edited Mar 24, 2019 by marc_s

1 Answer

2

You have a very large array which presently is part of a variable with automatic lifetime that the compiler places on the stack. Since it's too big to fit, you get a stack overflow.

Replace your array declared as

double heightmap[Constants::WorldWidth][Constants::WorldHeight];

by

std::unique_ptr<double [][Constants::WorldHeight]> heightmap{std::make_unique<double [][Constants::WorldHeight]>(Constants::WorldWidth)};

You will also have to #include <memory> if you haven't already.

Nothing else needs to change1. make_unique will allocate the storage for the same exact contiguous 2-D array you had before, only it will be dynamically allocated instead of taking up stack space. And unique_ptr is smart enough to automatically free the storage when the class instance that owns it goes away.


1 Only probably true. std::unique_ptr<Type[]> supports subscripting with [], so your current code heightmap[x][y] will continue working. If you used array-to-pointer decay anywhere without subscripting, you will now need heightmap.get() or &heightmap[0][0] instead of just the bare array name.

answered on Stack Overflow Mar 19, 2019 by Ben Voigt • edited Mar 19, 2019 by Ben Voigt

User contributions licensed under CC BY-SA 3.0