Исключение C ++ WINAPI Необработанное переполнение стека до достижения кода - PullRequest
0 голосов
/ 19 марта 2019

Я собрал симпатичный маленький двигатель местности в прямой х.Я изменил 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 Iполучить ошибку переполнения стека в самом начале моего кода, так рано, что я не могу продолжать отладку, чтобы увидеть, что идет не так.

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

У него есть один пустой конструктор.

1 Ответ

2 голосов
/ 20 марта 2019

У вас очень большой массив, который в настоящее время является частью переменной с автоматическим временем жизни, которое компилятор помещает в стек. Поскольку он слишком велик для размещения, вы получаете переполнение стека.

Замените ваш массив, объявленный как

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 выделит хранилище для того же точного непрерывного двумерного массива, который у вас был ранее, только оно будет выделяться динамически, а не занимать место в стеке. И unique_ptr достаточно умен, чтобы автоматически освобождать хранилище, когда экземпляр класса, которому он принадлежит, исчезает.


1 Только, вероятно, правда. std::unique_ptr<Type[]> поддерживает подписку с [], поэтому ваш текущий код heightmap[x][y] продолжит работать. Если вы использовали где-нибудь затухание массива в указатель без подписки, теперь вам понадобится heightmap.get() или &heightmap[0][0] вместо простого имени массива.

...