简体   繁体   中英

Allocating 2d array of chars

Constructor

This is how I'm allocating it:

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;

Inside the class, it's:

char ***board;

Destructor:

Now I want to delete it, so I wrote this (the board it the class field):

for(i = 0; i < width; i++)
    delete (*board)[i];
delete (*board);

When running this:

Board* b = new Board(16, 30, 99);
delete b;

I get an Unhandled exception. Why?

You are storing a pointer to a variable on the stack, which becomes invalid as soon as the constructor returns. You should declare your class's data member as char **board and assign this->board = board .

EDIT: See also @Kerrek SB's comment. The local variable is redundant. Just use the data member directly (without the this-> ).

EDIT 2: Rectangular arrays are best created as a single array, using pointer arithmetic to index (which is what the compiler does with declared 2D arrays anyway):

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]; }

This has the advantage of requiring just one memory allocation (and therefore one delete[] ). It also improves cache locality because the cells are contiguous.

Even better, if you know the dimensions at compile-time, use templates:

template <int W, int H>
class Board {
    char board[W][H];
    ...
};
...
Board<8, 8>* b = new Board<8, 8>(...);

This requires no memory allocation at all (other than the new Board , of course).

Anything that you new you need to delete , in the exact same way:

board = new char*[width];
...
board[i] = new char[height];
...
...
delete[] board[i];
delete[] board;

No dereferencing is needed in this case.

You should use the powers of 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);
    }
};

All you've got to do now is board[y].push_back(char_x_val) in order to append a new element to the end. You can treat board[y][x] just like any other 2D array (well, almost), but not worry about the deallocation.

Read up more on vectors here . (Anyone know a good tutorial?)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM