到达代码之前的 C++ WINAPI 异常未处理堆栈溢出
C++ WINAPI Exception Unhandled Stack Overflow before reaching code
我在 direct x 中组装了一个不错的小地形引擎。我将土地的 width
和 height
从 256
更改为 512
,现在当我 运行 调试器时,程序在 wWinMain
中崩溃。 Width
和 Height
是 const 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>
。
无需更改其他内容1。 make_unique
将为您之前拥有的完全相同的连续二维数组分配存储空间,只是它会动态分配而不是占用堆栈 space。 unique_ptr
足够聪明,可以在拥有它的 class 实例消失时自动释放存储。
1 只可能是真的。 std::unique_ptr<Type[]>
支持使用 []
进行下标,因此您当前的代码 heightmap[x][y]
将继续工作。如果您在没有下标的情况下在任何地方使用数组到指针衰减,您现在将需要 heightmap.get()
或 &heightmap[0][0]
而不仅仅是裸数组名称。
我在 direct x 中组装了一个不错的小地形引擎。我将土地的 width
和 height
从 256
更改为 512
,现在当我 运行 调试器时,程序在 wWinMain
中崩溃。 Width
和 Height
是 const 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>
。
无需更改其他内容1。 make_unique
将为您之前拥有的完全相同的连续二维数组分配存储空间,只是它会动态分配而不是占用堆栈 space。 unique_ptr
足够聪明,可以在拥有它的 class 实例消失时自动释放存储。
1 只可能是真的。 std::unique_ptr<Type[]>
支持使用 []
进行下标,因此您当前的代码 heightmap[x][y]
将继续工作。如果您在没有下标的情况下在任何地方使用数组到指针衰减,您现在将需要 heightmap.get()
或 &heightmap[0][0]
而不仅仅是裸数组名称。