这就是我分配它的方式:
char **board = new char*[width];
for(i = 0; i < width; i++){
board[i] = new char[height];
for(j = 0; j < height; j++)
board[i][j] = 0;
}
this->board = &board;
在课堂上,它是:
char ***board;
现在我想删除它,所以我写了这个(它是类字段的板子):
for(i = 0; i < width; i++)
delete (*board)[i];
delete (*board);
运行时:
Board* b = new Board(16, 30, 99);
delete b;
我收到一个未处理的异常。为什么呢?
答案 0 :(得分:8)
您正在存储指向堆栈上变量的指针,一旦构造函数返回该指针就会变为无效。您应该将班级的数据成员声明为char **board
并指定this->board = board
。
编辑:另见@Kerrek SB的评论。局部变量是多余的。只需直接使用数据成员(不含this->
)。
编辑2:矩形数组最好创建为单个数组,使用指针算法进行索引(这是编译器对声明的2D数组执行的操作):
char *board;
...
board = new char[width*height];
for(i = 0; i < width*height; ++i){
board[i] = 0;
}
...
char& operator()(int i, int j) { return board[width*i + j]; }
这样做的好处是只需要一次内存分配(因此需要一个delete[]
)。它还改善了缓存局部性,因为单元格是连续的。
更好的是,如果您在编译时知道维度,请使用模板:
template <int W, int H>
class Board {
char board[W][H];
...
};
...
Board<8, 8>* b = new Board<8, 8>(...);
这根本不需要内存分配(当然除new Board
之外)。
答案 1 :(得分:3)
您new
所需的任何内容delete
,完全相同:
board = new char*[width];
...
board[i] = new char[height];
...
...
delete[] board[i];
delete[] board;
在这种情况下不需要取消引用。
答案 2 :(得分:1)
你应该使用C ++的强大功能。
class Board
{
std::vector<std::vector<char>> board;
public:
Board(std::vector<std::vector<char>> const& board) : board(board) {}
Board(size_t x, size_t y, char val = 0)
{
std::vector<char> x2(x, val);
this->board(y, x2);
}
};
现在你要做的就是board[y].push_back(char_x_val)
,以便在最后附加一个新元素。您可以像处理任何其他2D数组一样处理board[y][x]
(好吧,差不多),但不要担心重新分配。
了解有关向量here的更多信息。 (任何人都知道一个很好的教程吗?)