You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++开发象棋引擎调用std::cout后Piece指针二维数组损坏求助

问题根源

你在Chess类构造函数中定义的Rook bq_r(black)、Knight bq_n(black)等所有棋子实例都是栈上的局部临时对象,它们的生命周期仅存在于构造函数执行阶段。构造函数执行结束后,这些局部对象占用的栈内存会被系统回收复用,存储在board数组里的指针全部变成悬垂指针,后续访问这些指针指向的内存属于未定义行为,就会出现输出乱码、内容随机变化、数组莫名损坏的现象。
你调试看到的print_board刚进入时数组内容正常,是因为此时对应栈内存还未被其他操作覆盖;执行std::cout操作会占用栈空间修改废弃内存,就出现了执行一次输出后数组损坏的现象。

修复方案

这里提供两种适配不同需求的修复方案:

方案1:堆内存存储棋子实例(灵活度高)

用new关键字在堆上创建棋子对象,堆对象的生命周期可以手动控制,不会随构造函数结束销毁:

// 修改chessBoard.cpp中的构造函数
Chess::Chess()
{
    // 黑方后排棋子,改为堆上创建
    board[0][0] = new Rook(black);
    board[0][1] = new Knight(black);
    board[0][2] = new Bishop(black);
    board[0][3] = new Queen(black);
    board[0][4] = new King(black);
    board[0][5] = new Bishop(black);
    board[0][6] = new Knight(black);
    board[0][7] = new Rook(black);
    // 其余位置棋子同理创建
}

需要额外给Chess类添加析构函数,遍历数组释放堆内存避免泄漏:

// chessBoard.h中添加析构声明
class Chess
{
private:
    Piece* board[8][8] = {};
public:
    Chess();
    ~Chess();
    void print_board();
};

// chessBoard.cpp实现析构逻辑
Chess::~Chess() {
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            delete board[i][j];
        }
    }
}

方案2:棋子作为Chess类成员(性能更高,适合引擎场景)

把所有棋子实例定义为Chess类的成员,生命周期和Chess对象绑定,不需要手动管理内存:

// chessBoard.h修改私有成员
class Chess
{
private:
    // 预先定义所有棋子成员
    Rook bq_r{black}, bk_r{black}, wq_r{white}, wk_r{white};
    Knight bq_n{black}, bk_n{black}, wq_n{white}, wk_n{white};
    Bishop bq_b{black}, bk_b{black}, wq_b{white}, wk_b{white};
    Queen b_q{black}, w_q{white};
    King b_k{black}, w_k{white};
    Pawn b_pawns[8]{{black},{black},{black},{black},{black},{black},{black},{black}};
    Pawn w_pawns[8]{{white},{white},{white},{white},{white},{white},{white},{white}};
    Piece* board[8][8] = {};
public:
    Chess();
    void print_board();
};

// chessBoard.cpp构造函数直接赋值成员地址
Chess::Chess()
{
    board[0][0] = &bq_r;
    board[0][1] = &bq_n;
    board[0][2] = &bq_b;
    board[0][3] = &b_q;
    board[0][4] = &b_k;
    board[0][5] = &bk_b;
    board[0][6] = &bk_n;
    board[0][7] = &bk_r;
    // 其余赋值逻辑不变
}

内容的提问来源于stack exchange,提问作者kiran_isaac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 02:21:01