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.
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.
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.