到达代码之前的 C++ WINAPI 异常未处理堆栈溢出

C++ WINAPI Exception Unhandled Stack Overflow before reaching code

我在 direct x 中组装了一个不错的小地形引擎。我将土地的 widthheight256 更改为 512,现在当我 运行 调试器时,程序在 wWinMain 中崩溃。 WidthHeightconst static unsigned int 我应该补充一点,如果我将数字改回 256,则程序可以正常调试而不会出错。只有在更改这些数字时才会抛出堆栈溢出错误。

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

当将 WorldWidth 或 WorldHeight 更改为大于 256 的数字时,我在代码的最开始收到堆栈溢出错误,太早以至于我无法进一步正确调试以查看出了什么问题。

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);

任何人都可以解释发生了什么,因为我无法通过通向 wWinMain 方法的第一个大括号进行调试,而且我不明白更改这两个值如何导致程序抛出此错误。

World 在 Game 头文件中声明为原始的、普通的私有成员。

World world;

它有一个空的构造函数。

你有一个非常大的数组,它目前是编译器放在堆栈上的具有自动生命周期的变量的一部分。由于它太大放不下,您会出现堆栈溢出。

替换声明为

的数组
double heightmap[Constants::WorldWidth][Constants::WorldHeight];

来自

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

如果你还没有,你也必须 #include <memory>

无需更改其他内容1make_unique 将为您之前拥有的完全相同的连续二维数组分配存储空间,只是它会动态分配而不是占用堆栈 space。 unique_ptr 足够聪明,可以在拥有它的 class 实例消失时自动释放存储。


1 只可能是真的。 std::unique_ptr<Type[]> 支持使用 [] 进行下标,因此您当前的代码 heightmap[x][y] 将继续工作。如果您在没有下标的情况下在任何地方使用数组到指针衰减,您现在将需要 heightmap.get()&heightmap[0][0] 而不仅仅是裸数组名称。