Ошибка перебора двумерного массива объектов класса c++

имеется класс Chess, который содержит свойство field - двумерный массив объектов класса Cell. Cell, в свою очередь, содержит свойство figure - объект абстрактного класса Figure. Проблема появляется, когда я пытаюсь перебрать двумерный массив field. Текст ошибки: Вызвано исключение по адресу 0x0000000000000000 в Chess.exe: 0xC0000005: нарушение прав доступа при исполнении по адресу 0x0000000000000000. Ошибка возникает только при обращении к методу GetName объекта Pawn, который содержится в Cell в field0, но до этого, когда в цикле вызывается этот же метод внутри field[0][0], никакой ошибки нет, и в консоль выводится нужная мне информация.

Соответственно, если сделать массив размером 1, то ошибки тоже нет, но при увеличении размера внутреннего массива хотя бы на 1, ошибка сразу возникает.

При этом, если в режиме отладки посмотреть на значения field[1][0] и field[1][0], то они, как будто бы, ссылаются на одни и тот же объект, но я не понимаю, как такое может происходить.

Скриншот и код прикрепил. Ошибка возникает на строке 81.

Подскажите, пожалуйста, где я допускаю ошибку :(

#include <map>
#include <iomanip>
#include <typeinfo>
using namespace std;


enum class Color { white, black };
map <Color, string> stringColor = {
        {Color::white, "White"},
        {Color::black, "Black"}
};

class Figure
{
public:
    Figure(Color figureColor)
    {
        this->color = figureColor;
    }

    Color GetColor(void) const
    {
        return color;
    }

    virtual string GetName(void) = 0;

protected:
    Color color;

};


class Pawn :public Figure {
public:
    Pawn(Color pawnColor) :Figure(pawnColor) 
    {
    };

    string GetName(void) override {
        return "Pawn";
    };
};

class Cell
{
private:
    Color color;
    Figure* figure;

public:
    Cell()
    {
        color = Color::white;
        figure = NULL;
    }
    Cell(Color cellColor)
    {
        color = cellColor;
        figure = NULL;
    }

    void SetFigure(Figure* newFigure) {
        this->figure = newFigure;
    }

    Figure* GetFigure(void) {
        return figure;
    }

    string ToString()
    {
        if (figure == NULL)
        {
            return stringColor[color];
        }
        else
        {
            string figureColor = stringColor[figure->GetColor()];
            string name = figure->GetName();
            string result = name + "[" + figureColor + "]";
            return result;
        }
    }
};

class Chess
{
private:
    Cell field[1][2];

    void CreateField(void)
    {
        bool isWhite = true;
        for (int i = 0; i < 1; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                field[i][j] = Cell(isWhite ? Color::white : Color::black);
                isWhite = !isWhite;
            }
            isWhite = !isWhite;
        };
    }

    void SetStartingLineUp(void)
    {
        for (int i = 0; i < 1; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                Color color = i == 1 ? Color::black : Color::white;
                Pawn pawn(color);
                field[i][j].SetFigure(&pawn);
            }
        };

    }
public:
    Chess(void)
    {
        CreateField();
        SetStartingLineUp();

    }

    void ShowField(void)
    {
        for (int i = 0; i < 1; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                cout << setw(10) << field[i][j].ToString();
            }
            cout << endl;
        };
    }
};

int main()
{
    setlocale(LC_ALL, "rus");

    Chess chess;
    chess.ShowField();

    int a;
    cin >> a;
}

Значение переменных в режиме отладке на строке 134


Ответы (1 шт):

Автор решения: Harry
Pawn pawn(color);
field[i][j].SetFigure(&pawn);

....

void SetFigure(Figure* newFigure) {
    this->figure = newFigure;
}

Т.е. передаем и сохраняем адрес локального объекта, который немедленно после этого вызова умирает...

Хотя бы

field[i][j].SetFigure(new Pawn(color));

или иным способом, не хранящим указатель на локальный объект, т.е. по сути висящую ссылку.

Само собой, в новом варианте надо озаботиться корректным освобождением памяти...

→ Ссылка