分配2d字符数组

时间:2011-09-18 22:07:20

标签: c++ arrays memory memory-management new-operator

构造

这就是我分配它的方式:

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;

我收到一个未处理的异常。为什么呢?

3 个答案:

答案 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的更多信息。 (任何人都知道一个很好的教程吗?)