为什么只调用数组元素[3][..]或[4][..]会导致EXC_BAD_ACCESS

Why would calls only to array elements [3][...] or [4][...] cause EXC_BAD_ACCESS?

本文关键字:ACCESS EXC BAD 调用 数组元素 为什么      更新时间:2023-10-16

我正在用C++编写一个2D游戏。我创建了一个名为BitBoard的类来表示整个游戏板,并管理游戏的逻辑,以便将其与图形和输入处理分离。BitBoard类包含ints的二维阵列(命名为bits),其中1的值表示占用空间,0的值表示空闲空间。在BitBoard内部是称为readBit(int x, int y)setBit(int x, int y)zeroBit(int x, int y)的函数。出于某种原因,如果x是3或4,这些函数调用中的任何一个都会导致EXC_BAD_ACCESS错误,但在其他任何时候都不会。bits是3x3元素、4x4元素、10x10元素、100x100元素等都无关紧要,只有bits[3][...]bits[4][...]会引起任何问题。下面我发布了相关代码。我就是不明白是什么导致了这个错误。

/* BitBoard.h */

#ifndef BITBOARD_H
#define BITBOARD_H
class BitBoard {
private:
int board_width;
int board_height;
int view_width;
int view_height;
int* bits[];
public:
BitBoard();
BitBoard(int widthIn, int heightIn);
int getViewWidth();
int getViewHeight();
void zeroBit (int x, int y);
void setBit (int x, int y);
int readBit (int x, int y);
#endif

/* BitBoard.cpp */

#include "BitBoard.h"
BitBoard::BitBoard() {
board_width = 0;
board_height = 0;
view_width = 0;
view_height = 0;
for (int i = 0; i < board_width; i++) {
//bits = (new int[board_width*board_height]);
bits[i] = new int[board_height];
}
for (int i = 0; i < board_width; i++) {
for (int j = 0; j < board_height; j++) {
zeroBit(i, j);
}
}
}
BitBoard::BitBoard(int widthIn, int heightIn) {
board_width = widthIn;
board_height = heightIn;
view_width = widthIn;
view_height = heightIn;
for (int i = 0; i < board_width; i++) {
//bits = (new int[board_height*board_width]);
bits[i] = new int[board_height];
}
for (int i = 0; i < board_width; i++) {
for (int j = 0; j < board_height; j++) {
zeroBit(i, j);
}
}
}
int BitBoard::getViewWidth() {
return view_width;
}
int BitBoard::getViewHeight() {
return view_height;
}
void BitBoard::zeroBit (int x, int y) {
bits[x][y] = 0;
}
void BitBoard::setBit (int x, int y) {
bits[x][y] = 1;
}
int BitBoard::readBit (int x, int y) {
return bits[x][y];
}

我最初有一个函数,它将整个电路板打印出来以进行调试(这就是我最初发现错误的原因)。我以为我把这个打印函数写错了,是它造成了问题,但经过多次重写,我只是把以下代码放在了main():中

#include <cstdlib>
#include "BitBoard.h"
...
BitBoard bb1(10, 10);
...
cout << "1: " << "|| " << bb1.readBit(0, 0) << " |" << "| " << bb1.readBit(0, 1) << " |" << "| " << ... << bb1.readBit(0, 9) << " ||" <<  endl;
cout << "2: " << "|| " << bb1.readBit(1, 0) << " |" << "| " << bb1.readBit(1, 1) << " |" << "| " << ... << bb1.readBit(1, 9) << " ||" <<  endl;
cout << "3: " << "|| " << bb1.readBit(2, 0) << " |" << "| " << bb1.readBit(2, 1) << " |" << "| " << ... << bb1.readBit(2, 9) << " ||" <<  endl;
cout << "4: " << "|| " << bb1.readBit(3, 0) << " |" << "| " << bb1.readBit(3, 1) << " |" << "| " << ... << bb1.readBit(3, 9) << " ||" <<  endl;
cout << "5: " << "|| " << bb1.readBit(4, 0) << " |" << "| " << bb1.readBit(4, 1) << " |" << "| " << ... << bb1.readBit(4, 9) << " ||" <<  endl;
cout << "6: " << "|| " << bb1.readBit(5, 0) << " |" << "| " << bb1.readBit(5, 1) << " |" << "| " << ... << bb1.readBit(5, 9) << " ||" <<  endl;
cout << "7: " << "|| " << bb1.readBit(6, 0) << " |" << "| " << bb1.readBit(6, 1) << " |" << "| " << ... << bb1.readBit(6, 9) << " ||" <<  endl;
cout << "8: " << "|| " << bb1.readBit(7, 0) << " |" << "| " << bb1.readBit(7, 1) << " |" << "| " << ... << bb1.readBit(7, 9) << " ||" <<  endl;
cout << "9: " << "|| " << bb1.readBit(8, 0) << " |" << "| " << bb1.readBit(8, 1) << " |" << "| " << ... << bb1.readBit(8, 9) << " ||" <<  endl;
cout << "10: " << "|| " << bb1.readBit(9, 0) << " |" << "| " << bb1.readBit(9, 1) << " |" << "| " << ... << bb1.readBit(9, 9) << " ||" <<  endl;

每一行(当程序运行时)都会打印出一个字符串1: || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||

在这种形式下,程序将不起作用,我会得到一个EXC_BAD_ACCESS错误。但是,如果我只注释以cout << "4: "cout << "5: "开头的两行,程序就可以完美地工作。正如我所说,无论实际数组有多大,甚至我如何访问这些元素,它们总是会导致崩溃。我可以将bb1.readBit(2,0)bb1.writeBit(2,0)bb1.zeroBit(2,0)放在程序中的任何位置,而不会出现任何问题,但x=3或4的任何一个都会导致相同的问题。我已经尝试将类中的所有内容公开,但遇到了相同的问题,即使是直接访问main()中的值。我已尝试将头文件更改为.hpp。我真的不知道问题出在哪里,尤其是因为BitBoard的构造函数本身甚至可以毫无问题地使用zeroBit()。我在这里俯瞰什么?真的很简单吗?我的电脑本身坏了吗?任何见解都值得赞赏。

因为bits空的指针数组。无论您使用什么作为索引,它都是越界的。

如果您希望它是动态的,请使用std::vector。事实上,我推荐一个整数向量的向量:

std::vector<std::vector<int>> bits;