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

C++井字棋游戏vector下标越界问题求助

问题原因与修复方案

核心错误:递归调用未返回结果

你的player_turn函数在触发递归时,没有把递归调用的返回值传递出去。当你输入无效内容触发else块后,递归的player_turn会正常获取有效输入并返回正确的guess,但上层的函数调用在执行完player_turn(board);后,没有return这个结果,导致最初调用的player_turn函数没有返回值,最终返回的是未定义的垃圾整数。主函数里用这个垃圾值减1后,必然会超出vector的下标范围,触发"Vector subscript out of range"错误。

看这段错误代码:

else {
    std::cout << "Invalid input! Try again\n";
    player_turn(board); // 这里没有return,上层函数无返回值
}

额外问题:传值导致不必要的复制

函数参数std::vector<char> board是传值调用,每次递归都会复制一个新的棋盘副本,虽然当前逻辑里判断空位不受影响,但会浪费内存和性能,应该改成传引用。

可选优化:处理非整数输入

如果用户输入字母、符号这类非整数内容,std::cin会进入错误状态,导致后续输入全部失败并无限循环,需要添加错误处理逻辑。

修复后的完整代码

#include <iostream>
#include <vector>
#include <limits> // 用于清除输入缓冲区

int player_turn(std::vector<char>& board) { // 改成传引用
    int guess;
    std::cout << "Please enter field 1-9: \n";
    // 处理非整数输入的情况
    while (!(std::cin >> guess)) {
        std::cin.clear(); // 清除错误标志
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 忽略缓冲区的垃圾内容
        std::cout << "Invalid input! Enter a number between 1-9: \n";
    }
    if (guess < 10 && guess > 0 && board[guess-1] == '-') {
        return guess;
    } else {
        std::cout << "Invalid input! Try again\n";
        return player_turn(board); // 递归调用时返回结果
    }
}

// 主函数调用示例
int main() {
    std::vector<char> board = {'-', '-', '-', '-', '-', '-', '-', '-', '-'}; // 修正为9个位置的井字棋棋盘
    board[player_turn(board) - 1] = 'O';
    return 0;
}

关键修改点说明

  1. 递归返回结果:在else块里把player_turn(board);改成return player_turn(board);,确保每一层递归的结果都能正确传递到最上层调用。
  2. 传引用代替传值:函数参数改为std::vector<char>& board,避免每次递归复制棋盘,同时保证对棋盘的判断是基于原始数据。
  3. 非整数输入处理:添加while循环处理cin的错误状态,清除缓冲区的无效内容,避免无限循环。
  4. 修正棋盘大小:你原来定义的棋盘有10个'-',井字棋只需要9个位置,多余的一个会导致逻辑冗余,这里也一并修正了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:30:54