C ++缓冲区溢出

时间:2014-08-20 12:35:20

标签: c++ buffer-overrun

我正在学习C ++,虽然我对C#有一个合理的理解,但我以前从未遇到过这个问题。通过一个简单的程序,将棋子放在一个假想的棋盘上(一个枚举的数组),然后分配在棋子开头就有棋子的方块,然后你会被要求提供坐标,程序会返回该方格上的内容。它显示正确的部分,但在非调试模式下将始终崩溃,并在Visual Studio调试中显示缓冲区溢出。它很短,所以我会显示所有代码。

#include <iostream>
#include <string>
using namespace std;
int main() {
enum Chessboard {
    Blank,
    Pawn,
    Rook,
    Knight,
    Bishop,
    King,
    Queen
};
Chessboard board[8][8] = { Blank };
for (int x = 1; x < 8; x++)
{
    board[1][x] = Pawn;
    board[8][x] = Pawn;
}
board[7][0] = Rook;
board[7][1] = Knight;
board[7][2] = Bishop;
board[7][3] = King;
board[7][4] = Queen;
board[7][5] = Bishop;
board[7][6] = Knight;
board[7][7] = Rook;
board[0][0] = Rook;
board[0][1] = Knight;
board[0][2] = Bishop;
board[0][4] = King;
board[0][3] = Queen;
board[0][5] = Bishop;
board[0][6] = Knight;
board[0][7] = Rook;

int X = 0;
int Y = 0;
bool Error = false;
cout << "Enter the coordinates of a square on a chessboard to see what is on there at    the start of the game (1 number at a time)" << endl;
do {
    cin >> X;
    X--;
    Error = false;
    if (X < 0 || X > 7)
    {
        cout << "That's not on the board" << endl;
        Error = true;
    }
} while (Error = false);
do {
    cin >> Y;
    Y--;
    Error = false;
    if (Y < 0 || Y > 7)
    {
        cout << "That's not on the board" << endl;
        Error = true;
    }
} while (Error = false);

string Name = "";
Chessboard Piece = board[X][Y];
switch (Piece)
{
case Blank: Name = "nothing";
    break;
case Pawn: Name = "a Pawn";
    break;
case Rook: Name = "a Rook";
    break;
case Knight: Name = "a Knight";
    break;
case Bishop: Name = "a Bishop";
    break;
case King: Name = "a King";
    break;
case Queen: Name = "a Queen";
    break;
default: Name = "Somehow you missed the board";
    break;
} 

cout << "On " << ++X << "," << ++Y << " there is " << Name << endl;

return 0;
}

5 个答案:

答案 0 :(得分:2)

你超出了矩阵的界限

   board[1][x] = Pawn;
   board[8][x] = Pawn;

你宣布它是8x8所以要使用索引0..7。

答案 1 :(得分:2)

你肯定会在这里得到超支:

Chessboard board[8][8] = { Blank };
for (int x = 1; x < 8; x++)
{
  board[1][x] = Pawn;
  board[8][x] = Pawn; 
}

没有board[8][]。您有board[0][]board[7][]可用。

答案 2 :(得分:1)

在C中,C ++和C#数组索引从0开始到数组的大小 - 1.例如这个循环

for (int x = 1; x < 8; x++)
{
    board[1][x] = Pawn;
    board[8][x] = Pawn;
}

必须重写为

for ( int x = 0; x < 8; x++)
{
    board[1][x] = Pawn;
    board[6][x] = Pawn;
}

如果数组定义为

Chessboard board[8][8] = { Blank };

同样最好为魔术数字8引入助记符名称并使用此名称而不是数字。

答案 3 :(得分:0)

for (int x = 0; x < 8; x++)
{
    board[0][x] = Pawn;
    board[7][x] = Pawn;
}

我认为7是这个数组的最大值。

答案 4 :(得分:0)

正如其他人所说,导致错误的board[8][x] = Pawn

虽然这似乎是一个测试程序,而不是将要投入生产的东西,但仍然需要提醒我一句谨慎,总是尽量避免在代码中使用数字/硬编码字符串/整数或其他任何内容因为你通常最终会做这样的事情。有一天,当项目投入生产并且可能是你的老板决定将价值改为100 x 100时,你将很难做到。

良好的方法:

static const int BoardSize = 10;

#define BoardSize 10;