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

问题描述 投票:-3回答:1

我在直接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的数字时,我在代码的最开始就出现堆栈溢出错误,所以我很早就无法正确调试以查看出现了什么问题。

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

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

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

World world;

它有一个空的构造函数。

c++ winapi memory directx stack-overflow
1个回答
2
投票

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

替换声明为的数组

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

通过

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

如果你还没有,你还需要#include <memory>

没有什么需要改变1。 make_unique将为之前相同的连续2-D数组分配存储空间,只会动态分配存储空间而不占用堆栈空间。并且unique_ptr非常聪明,可以在拥有它的类实例消失时自动释放存储空间。


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

© www.soinside.com 2019 - 2024. All rights reserved.