对象的 C++ 实例无法读取内存

标签 c++ pointers object c++11 reference

我需要一些有关 C++ 和对象\引用\指针的帮助。我正在编写一个包含多个类的简单国际象棋程序。特别是我对以下两个类 Board 和 Cell 有疑问:

棋盘有一个由单元格 vector 组成的 vector (基本上是一个矩阵)。每个单元格都包含一个指向当前占据它的部分的指针。

class Board
{
public:
    Board();
    void drawBoard();
    bool makeMove(int startRow, int startCol, int destRow, int destCol);
private:
    vector< vector<Cell> > _board;
    void initBoard();
    void initPieces();
};

Board::Board()
{
    initBoard();
}

void Board::initBoard()
{

    for (int i = 0; i < BOARD_SIZE; i++)
    {
        vector<Cell> row; //create empty row
        for (int j = 0; j < BOARD_SIZE; j++)
        {
            row.push_back((Cell(i, j)));
        }
        _board.push_back(row);
    }

    initPieces();
}

void Board::initPieces()
{
    //Set Pawns
    for (int i = 0; i < BOARD_SIZE; i++)
    {
        _board[1][i].setOccupying(new Pawn(White));
        _board[6][i].setOccupying(new Pawn(Black));
    }
}

void Board::drawBoard()
{

    drawLettersCoord();
    for (int i = BOARD_SIZE-1; i >= 0; i--)
    {
        std::cout << i + 1 << " ";
        for (int j = 0; j < BOARD_SIZE; j++)
        {       
            _board[i][j].draw();
        }
        std::cout << " " << i + 1 << std::endl;
    }
    std::cout << "\n";

}

bool Board::makeMove(int startRow, int startCol, int destRow, int destCol)
{
    _board[startRow][startCol].getOccupyingPiece()->isLegalMove(
        startRow, startCol, destRow, destCol);
    return true;
}

这是 Cell 类:

class Cell
{
public:
    Cell();
    Cell(int row, int col);
    Cell(int row, int col, ChessPiece * occupying);
    void draw();
    ChessPiece * getOccupyingPiece();
    void setOccupying(ChessPiece *occupying);
private:
    int _row;
    int _col;
    bool _occupied;
    ChessPiece * _pieceOccupying;
};

Cell::Cell()
    :Cell(0, 0)
{
    setColour();
}

Cell::Cell(int row, int col)
    : _row(row), _col(col), _occupied(false)
{
    setColour();
}

Cell::Cell(int row, int col, ChessPiece * occupying)
    : _row(row), _col(col), _pieceOccupying(occupying), _occupied(true)
{
    setColour();
}

void Cell::setOccupying(ChessPiece *occupying)
{
    _occupied = true;
    _pieceOccupying = occupying;
}
void Cell::draw()
{

    int foregroundText;
    if (!_occupied)
    {
        foregroundText = 37;
    }
    else
    {
        foregroundText = _pieceOccupying->getPlayer();
    }
    cout << "\33[" << foregroundText << ";" << _colour << "m"
         << (_occupied ? _pieceOccupying->getPieceCode(): " ") << "\33[0m";
}

ChessPiece * Cell::getOccupyingPiece()
{
    return _pieceOccupying;
}

当我运行游戏时,我通过调用创建并绘制了一个新的棋盘

Board _board;
_board.drawBoard();

绘图似乎工作正常,没有任何问题。

但是,当我调用

_board.makeMove(1,0,2,0);

为了检查 pawn 是否可以走这样的一步,我得到了一个内存错误。调试后,我看到被调用的 Cell 对象中有垃圾,而不是实际数据。当我试图查看指向占用 block 的指针时,它显示“无法读取内存”,因此当我调用占用 block 的 isLegalMove 函数时,它崩溃了。

我似乎无法找出问题所在。我不明白为什么 vector 内的单元格中会有垃圾,它是在类中定义的(没有新的),所以根据我的理解,只要板的当前实例还活着,它就应该可用。

任何人都可以阐明我做错了什么吗?

最佳答案

  1. 并非 Cell 的所有构造函数都初始化 _occupied_pieceOccupying,这意味着它们在某些 中可能具有垃圾值单元格对象。

  2. 此外,您的 makeMove 无条件取消引用 getOc​​cupyingPiece() - 它不检查是否为空。

  3. 最后,您的棋盘上只有棋子,这意味着 (0, 0) 不包含棋子 - 因为 1.,Cell 对象在其 _pieceOccupying 中包含垃圾值,因此您访问随机内存并崩溃。

关于对象的 C++ 实例无法读取内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27840322/

相关文章:

c++ - Ogre Projector 透过物体发光

java - 帮助我理解这个指针与值的问题

c++ - 如何从双端队列中删除随机元素

javascript - 如何在 setInterval 和 setTimeout 函数中更改 "this"的范围

java - if 语句内创建的对象不起作用

C 或 C++ 中的 Java ByteArray 等价物

c++ - Turbo C++ 和 GCC(在 Windows 上使用代码块)以不同方式评估相同的三元表达式

c++ - 将 linting 添加到基于 autotools 的构建系统

C 函数删除字符串中的元音不起作用?

c - 如何访问给定指针的数据?