类中的 C++ int 被设置为值,似乎不知从何而来

c++ int in class gets set to value, seemingly out of nowhere

本文关键字:C++ int 设置      更新时间:2023-10-16

在某些条件下,int winner应该设置为 2,但它以某种方式被设置为各种更高的值,最常见的是 6。我不知道这是怎么发生的,因为我的类中没有其他函数会影响winner,而且该程序中甚至没有提到该变量。最让我困惑的是,我有一个几乎相同的函数(P2Move()(,它在将winner变量设置为P1Move()的方式上实际上是相同的,并且该函数完美运行。

一些信息:这是一部分的类称为 Board,它充当由 Square 类对象组成的棋盘数组。

下面是导致问题的函数。在底部附近,语句else if((canTake.size()==0)&&(canMove.size()==0)) {Board::winner = 2;}导致问题。当我从函数中删除有问题的部分时,其他一切似乎都可以工作,但我需要该部分才能提交最终项目。

void Board::P1Move()
{
P1pieces = 0;
std::vector <Move> canMove;
std::vector <Move> canTake;
for(int j = 0; j < bSize; j++)
{ //Start of j loop.
for(int i = 0; i < bSize; i++)
{ //Start of i loop.
Square sq = board[i][j];
bool cTakeL = canTakeL(i,j);
bool cTakeR = canTakeR(i,j);
bool cMoveL = canMoveL(i,j);
bool cMoveR = canMoveR(i,j);
if(board[i][j].getPl() == P1)
{
P1pieces++;
if(cTakeL)
{
Move a = Move(sq.getIndex(),board[i-2][j+2].getIndex(),board[i-1][j+1].getIndex(),0);
canTake.push_back(a);
}
if(cTakeR)
{
Move b = Move(sq.getIndex(),board[i+2][j+2].getIndex(),board[i+1][j+1].getIndex(),0);
canTake.push_back(b);
}
if(cMoveL)
{
Move c = Move(sq.getIndex(),board[i-1][j+1].getIndex(),0,0);
canMove.push_back(c);
}
if(cMoveR)
{
Move d = Move(sq.getIndex(),board[i+1][j+1].getIndex(),0,0);
setWinner(d.getSpos());
canMove.push_back(d);
}
}
} //End of i loop.
} //End of j loop.
if(canTake.size()!=0)
{
time_t t;
time(&t);
srand(t);
int moveNum = rand()%canTake.size();
std::string output = "p1 ";
Move out = canTake.at(moveNum);
int i = 0;
int j = 0;
for(int y = 0; y < bSize; y++)
{
for(int x = 0; x < bSize; x++)
{
if(board[x][y].getIndex()==out.getSpos())
{
i = x;
j = y;
}
}
}
if(board[i-2][j+2].getIndex()==out.getEndPos())
{
board[i-2][j+2].setOcc(true);
board[i-2][j+2].setPl(P1);
board[i-1][j+1].setOcc(false);
board[i-1][j+1].setPl(NA);
}
else if(board[i+2][j+2].getIndex()==out.getEndPos())
{
board[i+2][j+2].setOcc(true);
board[i+2][j+2].setPl(P1);
board[i+1][j+1].setOcc(false);
board[i+1][j+1].setPl(NA);
}
output = output + out.toString();
setCmove(output);
board[i][j].setOcc(false);
board[i][j].setPl(NA);
}
else if(canMove.size()!=0)
{
time_t t;
time(&t);
srand(t);
int moveNum = rand()%canMove.size();
std::string output = "p1 ";
Move out = canMove.at(moveNum);
int i = 0;
int j = 0;
for(int y = 0; y < bSize; y++)
{
for(int x = 0; x < bSize; x++)
{
if(board[x][y].getIndex()==out.getSpos())
{
i = x;
j = y;
}
}
}
if(board[i-1][j+1].getIndex()==out.getEndPos())
{
board[i-1][j+1].setOcc(true);
board[i-1][j+1].setPl(P1);
}
else if(board[i+1][j+1].getIndex()==out.getEndPos())
{
board[i+1][j+1].setOcc(true);
board[i+1][j+1].setPl(P1);
}
output = output + out.toString();
setCmove(output);
board[i][j].setOcc(false);
board[i][j].setPl(NA);
}
else if((canTake.size()==0)&&(canMove.size()==0))
{
Board::winner = 2;
}
P1pieces = canTake.size() + canMove.size();
}

您正在使用std::vector,这是一件好事。(太多初学者"C++"代码使用 C 数组。vector类模板提供了一种非常简单的方法来了解您是否以及在哪里可能具有越界访问权限(如注释中建议的那样(:

不要使用operator[]访问向量元素,而是更改代码以使用.at()成员函数。.at()是边界检查,如果您访问越界(而不是静默地破坏程序(,则会引发异常。

在生产代码中,通常首选operator[],因为省略边界检查更有效。但是在学习的同时,.at()可以为您提供很多帮助。

此外,养成使用代码检查器(如 valgrind 或assert宏(来检查假设的习惯是一件好事,即使您已经过了不再使用.at()的地步。