我做了一个运作良好的井字游戏。最近我决定添加一个重置游戏功能。 这是我从用户
输入的部分void playerMove() //Gets the player move and updates the box variables
{
int boxnumber;
while(1) //Set's loop if the player enters a invalid input
{
cout << "\n Player " << player << "'s turn!(Press 0 to reset the game!): ";
cin >> boxnumber;
if(box[boxnumber-1] == 'X' || box[boxnumber-1] == 'O' || boxnumber > 9 || boxnumber < 0) // Checks if the input is valid or not
{
system("CLS");//If invalid, show error and loop back to start to get new input
displayBoard();
cout << "\n Invalid Input! Try again!\n";
}else if(boxnumber == 0)
{
refreshGame();
displayBoard();
}else
{
box[boxnumber-1] = player;//If inputs are fine, set the box variable's and break out of loop!
break;
}
}
}
现在,在调试模式下,当我按0时,一切运行正常,游戏重置,但在发布版本中,当我按0时,它会给我“输入无效!再试一次!”
我尝试过的事情没有工作: - 重建整个发行版和调试版。 - 制作一个新项目并复制粘贴我的代码。同样的事情,调试工作,释放不。
对于任何想知道的人,我使用的是代码:: blocks IDE。编译器是GNU GCC。 谢谢您的帮助! :)
答案 0 :(得分:4)
您有未定义的行为。
在“第一个”if
中,您有box[boxnumber-1]
,因此当您输入0
时(正如您在问题中所述),您正在尝试访问带有索引的元素{ {1}}。那是UB,因为你正在读“无效”记忆。
您应该首先检查-1
(还有负数)。
答案 1 :(得分:3)
在if
语句中,将范围检查放在值检查的前面。也就是说,改变
if(box[boxnumber-1] == 'X' || box[boxnumber-1] == 'O' || boxnumber > 9 || boxnumber < 0)
到
if(boxnumber < 0 || box number > 9 || box[boxnumber-1] == 'X' || box[boxnumber-1] == 'O')
利用短路:如果输入值小于0或大于9,则不会执行值检查。这样可以避免检查box[10]
之类的内容,这些内容无效。
这仍然存在问题:如果用户输入0,则此代码将很高兴地检查box[-1]
,这也超出了范围。要摆脱这种情况,请移动在此部分前面测试if
的{{1}}语句的分支:
box number == 0