balarama
balarama

Reputation: 1

C++ Class constructor 2d Array memory allocation

I took a programming class at university this semester, just out of curiosity. We're doing C++ and I enjoyed it a lot, but the last two weeks have been rather steep for me and heres what troubles my mind:

I'm given a class interface as follows:

class GameOfLife(int rows, int cols);
    public:
        GameOfLife();
        void clear();
        void set(int row, int col, int value);
        void set(int row, int col, const char* values);
        int get(int row, int col);
        void print();
        void advance();
   };

First thing im being asked to do is to implement the constructor so that it allocates memory for a board with the amount of rows and cols passed in the argument. I thought i understood constructors but with this one I'm pretty lost. After i declared int rows and cols in the private section i thought about something along the lines of

GameOfLife::GameOfLife(int x, int y){
    rows = x;
    cols = y;
    board = new int* [rows];

But neither do i know how to handle the second dimension of the board without the compiler yelling at me nor do i know how to test if new memory is actually allocated properly. Any help? :(

Thanks in advance!

Upvotes: 0

Views: 599

Answers (5)

M.M
M.M

Reputation: 141554

There is already a class to dynamically manage memory, it's called vector. If you try to use new in your code then you end up having to reinvent the wheel and write dozens of lines of boilerplate that already exists inside vector.

Also it is simpler to store your board in a contiguous array, there is no need to use a bunch of separate memory blocks to hold the board.

Here is an example:

class GameOfLife
{
public:
    GameOfLife(int rows, int cols);
    void clear();
    void set(int row, int col, int value);
    void set(int row, int col, const char* values);
    int get(int row, int col);
    void print();
    void advance();
private:
    int rows, cols;
    std::vector<int> values;
};

// In the cpp file

GameOfLife::GameOfLife(int rows, int cols)
    : rows(rows), cols(cols), values(rows * cols) {}

void GameOfLife::set(int row, int col, int value)
    { values.at(row * cols + col) = value; }

int GameOfLife::get(int row, int col) 
    { return values.at(row * cols + col); }

Upvotes: 0

kjschiroo
kjschiroo

Reputation: 530

What you are doing right now with board = new int* [rows]; Is allocating an array of integer pointers. You still need to allocate the memory for the actual integers which is what thumbmunkey is doing with,

for(int i=0;i<rows;i++)
  board[i] = new int [cols];

Upvotes: 0

IrineK
IrineK

Reputation: 115

The essentials - constructor, destructor, getters:

    class GameOfLife
    {
    public:
        GameOfLife(int _rows, int _cols);
        ~GameOfLife ();

        int GetRows () {return rows;}
        int GetCols () {return cols;}
        int **GetBoard () {return board;}

    private:
        int rows, cols;
        int **board;
    };

    GameOfLife::GameOfLife(int _rows, int _cols)
    {
        rows = _rows;
        cols = _cols;
        board = new int *[rows];
        for (int i = 0; i<rows; i++)
            board[i] = new int[cols];
    }

    GameOfLife::~GameOfLife()
    {
        for (int i = 0; i<rows; i++)
            delete [] board[i];
        delete [] board;
    }

Upvotes: -1

thumbmunkeys
thumbmunkeys

Reputation: 20764

You have to allocate the column array for each row:

  for(int i=0; i<rows; i++)
      board[i] = new int [cols];

If the allocation fails (eg. when you're out of memory), you will get an exception.

Upvotes: 2

Barry
Barry

Reputation: 302767

In addition to thumbmunkey's correct answer, note that just because the external interface stipulates a 2D array doesn't mean the internal interface has to match.

You could have:

int* board = new int[rows * cols];

Where then instead of get() returning:

return board[x][y];

it would instead be:

return board[x * rows + y];

Sometimes one array is easier to think about than two. Sometimes it's not. Depends on how you want to do it (or if it's stipulated that you have to use one method or the other).

Upvotes: 2

Related Questions