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

C++象棋引擎接收用户移动指令时触发写访问错误求助

象棋引擎写访问错误排查与解决

开发基础C++象棋引擎时,通过用户输入字符串(例如输入1144代表从第1列第1行移动到第4列第4行)执行移动操作,触发写访问错误,Visual Studio调用栈如下:

ChessUltimate.exe!std::_String_val<std::_Simple_types>::_Large_string_engaged() Line 2282 C++
ChessUltimate.exe!std::_String_val<std::_Simple_types>::_Myptr() Line 2274 C++
ChessUltimate.exe!std::string::operator=(const std::string & _Right) Line 3230 C++
ChessUltimate.exe!ChessBoard::makeMove(int from_number, int from_letter, int to_number, int to_letter) Line 80 C++
ChessUltimate.exe!main() Line 18 C++

相关代码

ChessEngine.h

#pragma once

#include <iostream>
#include <sstream>

using namespace std;

class ChessBoard
{
    public:
        string** board;
        ChessBoard(string FEN)
        {
            // Make a 2D Array
            board = new string * [8]; // Rows
            for (int i = 0; i < 8; ++i)
            {
                board[i] = new string[8]; // Columns
            }

            // FEN parsing logic here
            int row = 7;
            int col = 0;

            for (char c : FEN)
            {
                if (isdigit(c))
                {
                    col += c - '0';
                }
                else if (c == '/')
                {
                    row--;
                    col = 0;
                }
                else if (c != ' ')
                {
                    board[row][col] = c;
                    col++;
                }
            }
        }
        
        ~ChessBoard()
        {
            for (int i = 0; i < 8; ++i)
            {
                delete[] board[i];
            }
            delete[] board;
        }

        void drawChessBoard()
        {
            for (int i = 7; i >= 0; --i)
            {
                cout << i + 1 << " ";
                for (int j = 0; j < 8; ++j)
                {
                    if (board[i][j].empty())
                    {
                        if ((i + j) % 2 == 0)
                            cout << "|#";
                        else
                            cout << "|_";
                    }
                    else
                    {
                        cout << "|" << board[i][j];
                    }
                }
                cout << "|\n";
            }
            cout << "   1 2 3 4 5 6 7 8\n";
        }

        void makeMove(int from_number, int from_letter, int to_number, int to_letter)
        {
            board [to_number-1][to_letter-1] = board[from_number-1][from_letter - 1];
            board [from_number-1][from_letter-1] = "";
        }
};

ChessUltimate.cpp(主文件)

#include <iostream>
#include "ChessBoard.h"

using namespace std;

ChessBoard* board;

int main()
{
    board = new ChessBoard("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR");
    board->drawChessBoard();
    while (true)
    {
        string move;
        cin >> move;
       
        board->makeMove(move[1], move[0], move[3], move[2]);
        board->drawChessBoard();
    }

    delete board;
}

问题根源与修复

核心问题

main函数中直接将move的字符值传递给makeMove的整数参数。例如输入字符'1',其ASCII值为49,而非整数1,导致计算后的数组索引为49-1=48,远超出棋盘数组的合法索引范围(0-7),触发内存越界写访问错误。

修复步骤

  1. 修正字符到整数的转换
    修改main函数中makeMove的调用代码,将字符转换为对应整数:

    board->makeMove(move[1] - '0', move[0] - '0', move[3] - '0', move[2] - '0');
    

    原理:ASCII中数字字符'0'到'9'是连续的,减去'0'即可得到对应的整数值。

  2. 添加输入合法性检查(推荐)
    避免用户输入非法格式导致错误,在处理移动前添加检查逻辑:

    while (true)
    {
        string move;
        cin >> move;
        
        // 检查输入长度是否为4
        if (move.size() != 4) {
            cout << "输入错误:请输入4位数字(如1144)\n";
            continue;
        }
        // 检查每个字符是否为1-8的数字
        bool valid = true;
        for (char c : move) {
            if (!isdigit(c) || c < '1' || c > '8') {
                valid = false;
                break;
            }
        }
        if (!valid) {
            cout << "输入错误:只能输入1-8的数字\n";
            continue;
        }
        
        board->makeMove(move[1] - '0', move[0] - '0', move[3] - '0', move[2] - '0');
        board->drawChessBoard();
    }
    
  3. 确认棋盘索引逻辑
    原代码中用户输入的行/列号(1-8)转换为数组索引(0-7)的逻辑正确,无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:30:56