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

程序触发Run-Time Check Failure #2,请求错误排查与代码审查

嘿,作为C++新手能写出这样的游戏框架已经超棒啦!咱们先搞定你遇到的栈损坏问题,再聊聊代码里的其他小细节~

问题根源:数组越界访问破坏栈内存

你碰到的Run-Time Check Failure #2 - Stack around the variable 'userInput' was corrupted,本质是数组越界访问破坏了栈上的其他变量内存:

  • 你定义的游戏棋盘是int gameBoard[4][19],这意味着行索引范围是0~3(共4行),列索引范围是0~18(共19列);
  • 但在showGrid和setupGame函数里,你用了for (int y = 0; y <= 4; y++)和for (int x = 0; x <= 19; x++),这会访问到不属于gameBoard的内存(比如gameBoard[4][...]、gameBoard[...][19]);
  • 栈内存是连续分配的,这些越界访问刚好覆盖了userInput的栈空间,所以错误提示指向了userInput,但问题根源在棋盘数组的循环边界错误。
修复步骤

1. 修正数组循环边界

把所有循环里的y <= 4改成y < 4,x <= 19改成x < 19,确保只访问数组的合法索引范围。

2. 修正出口位置和陷阱判断逻辑

  • 你原来设置出口的代码gameBoard[4][19] = 2是越界的,改成合法的gameBoard[3][18] = 2(对应棋盘右下角);
  • 陷阱生成的判断条件里,把(trapX == 19 && trapY == 4)改成(trapX == 18 && trapY == 3),避免覆盖出口位置。

3. 修复用户输入的逻辑错误

你注释掉的输入判断逻辑有问题:原来的if (userInput != "w" || userInput != "a" || ...)永远为真,应该用&&判断输入是否不在合法列表里。

修正后的完整代码
#include "stdafx.h"
#include <cstdlib>
#include <string>
#include <iostream>
#include <time.h>

// 用常量定义棋盘尺寸,方便后续修改
const int BOARD_ROWS = 4;
const int BOARD_COLS = 19;

// START FUNCTION DECLARATION
void setupGame(int gameBoard[BOARD_ROWS][BOARD_COLS]);
void showGrid(int gameBoard[BOARD_ROWS][BOARD_COLS]);
void calculateGame(std::string userInput, int gameBoard[BOARD_ROWS][BOARD_COLS], bool& bGameLoop);
// END FUNCTION DECLARATION

int main(int argc, char** argv) {
    std::string userInput = "";
    bool bGameLoop = true;
    int gameBoard[BOARD_ROWS][BOARD_COLS];

    setupGame(gameBoard);

    do {
        // Windows清屏用cls,Linux/macOS用clear
        system("cls");
        showGrid(gameBoard);

        // 读取用户输入
        userInput = "";
        std::cin >> userInput;

        // 判断输入合法性
        if (userInput != "w" && userInput != "a" && userInput != "s" && userInput != "d") {
            std::cout << "\nPlease use [W][A][S][D] to move <3\n";
            system("pause"); // 让用户看到提示后继续
        } else {
            calculateGame(userInput, gameBoard, bGameLoop);
        }

    } while (bGameLoop);

    return 0;
}

// START FUNCTION
/**
 * 处理游戏核心逻辑(移动、胜负判断等)
 * @param userInput 用户输入的方向
 * @param gameBoard 游戏棋盘数组
 * @param bGameLoop 游戏循环标志,用于结束游戏
 */
void calculateGame(std::string userInput, int gameBoard[BOARD_ROWS][BOARD_COLS], bool& bGameLoop) {
    // 先找到玩家当前位置
    int playerX = -1, playerY = -1;
    for (int y = 0; y < BOARD_ROWS; y++) {
        for (int x = 0; x < BOARD_COLS; x++) {
            if (gameBoard[y][x] == 1) {
                playerX = x;
                playerY = y;
                break;
            }
        }
        if (playerX != -1) break;
    }

    // 计算新位置
    int newX = playerX, newY = playerY;
    if (userInput == "w") newY--;
    else if (userInput == "s") newY++;
    else if (userInput == "a") newX--;
    else if (userInput == "d") newX++;

    // 检查新位置是否在棋盘内
    if (newX < 0 || newX >= BOARD_COLS || newY < 0 || newY >= BOARD_ROWS) {
        std::cout << "\nYou can't move there!\n";
        system("pause");
        return;
    }

    // 根据新位置内容处理逻辑
    switch (gameBoard[newY][newX]) {
        case 0: // 空位置,移动玩家
            gameBoard[playerY][playerX] = 0;
            gameBoard[newY][newX] = 1;
            break;
        case 2: // 到达出口,游戏胜利
            gameBoard[playerY][playerX] = 0;
            gameBoard[newY][newX] = 1;
            system("cls");
            showGrid(gameBoard);
            std::cout << "\nCongratulations! You escaped the dungeon!\n";
            bGameLoop = false;
            break;
        case 3: // 踩到陷阱,游戏失败
            gameBoard[playerY][playerX] = 0;
            gameBoard[newY][newX] = 1;
            system("cls");
            showGrid(gameBoard);
            std::cout << "\nOh no! You stepped on a trap! Game over!\n";
            bGameLoop = false;
            break;
    }
}

/**
 * 打印游戏棋盘
 */
void showGrid(int gameBoard[BOARD_ROWS][BOARD_COLS]) {
    std::cout << "DUNGEON CRAWL V1\n\n";
    std::cout << "#--------------------#\n";
    std::string cToOut;
    for (int y = 0; y < BOARD_ROWS; y++) {
        std::cout << "|";
        for (int x = 0; x < BOARD_COLS; x++) {
            switch (gameBoard[y][x]) {
                case 0: cToOut = " "; break;
                case 1: cToOut = "@"; break;
                case 2: cToOut = "X"; break;
                case 3: cToOut = "O"; break;
                default: cToOut = " "; break;
            };
            std::cout << cToOut;
        }
        std::cout << "|\n";
    }
    std::cout << "#--------------------#\n";
}

/**
 * 初始化游戏棋盘(玩家、出口、陷阱)
 */
void setupGame(int gameBoard[BOARD_ROWS][BOARD_COLS]) {
    // 0 = 空区域,1 = 玩家,2 = 出口,3 = 陷阱
    // 初始化棋盘为全空
    for (int y = 0; y < BOARD_ROWS; y++) {
        for (int x = 0; x < BOARD_COLS; x++) {
            gameBoard[y][x] = 0;
        }
    }

    // 设置玩家初始位置和出口
    gameBoard[0][0] = 1;
    gameBoard[BOARD_ROWS-1][BOARD_COLS-1] = 2;

    // 生成随机陷阱
    int trapX, trapY;
    bool bAlreadyUse = false;
    srand(time(NULL));
    for (int t = 1; t <= 5; t++) {
        do {
            trapX = rand() % BOARD_COLS;
            trapY = rand() % BOARD_ROWS;
            bAlreadyUse = (gameBoard[trapY][trapX] == 3);
            // 避免覆盖玩家初始位置和出口
        } while ((trapX == 0 && trapY == 0) || (trapX == BOARD_COLS-1 && trapY == BOARD_ROWS-1) || bAlreadyUse);
        gameBoard[trapY][trapX] = 3;
    }
}
// END FUNCTION
额外小建议
  • 用const定义棋盘尺寸常量(比如代码里的BOARD_ROWS和BOARD_COLS),后续修改棋盘大小更方便,也能避免手动写数字出错;
  • system("cls")和system("pause")是Windows平台特有的,如果要跨平台,可以用读取换行符的方式等待输入,用ANSI转义序列清屏;
  • 你原来的函数名calulateGame拼写错误,已经修正为calculateGame啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:14:49