Nicholas Corin
Nicholas Corin

Reputation: 2404

Dynamically allocating a 2D array of object pointers in a class

I'm struggling at the moment with the idea of dynamically allocating arrays at runtime. Coming from Java, used to just declaring the arrays in the class skeleton and only needing the size in the implementation.

This is what I've found to dynamically allocate 2D arrays:

Grid.h   
Block** grid;

Grid.cpp
grid = new Block*[size]
for(int i = 0 ; i < size ; i++)
    grid[i] = new Block[size]

This works pretty okay, although dealing with objects I've always been told that using pointers to objects rather than storing the objects themselves is much better performance wise. So when I tried to make the second dimension of arrays pointers like this:

Grid.cpp
grid = new Block*[size]
    for(int i = 0 ; i < size ; i++)
        grid[i] = new Block*[size];

When I changed my code to this, I got an error:

error: assigning to 'Block *' from incompatible type 'Block **'; dereference with *
        grid[i] = new Block* [size];
                ^ ~~~~~~~~~~~~~~~~~
                  *

Being slightly new to the C++ ways of doing things, can someone tell me what I'm doing wrong? Or even if I'm trying to do the wrong thing entirely?

Thanks in advance!

Upvotes: 0

Views: 4256

Answers (4)

Temple
Temple

Reputation: 1631

Alocating array of pointers can also be done in thread safe manner:

size_t allocatedRows = rowCount;
        try{
            array = new char*[allocatedRows];
            while(allocatedRows){
                --allocatedRows;
                array[allocatedRows] = new char[colCount];
            }
        }catch(std::bad_alloc& ex){
            while(++allocatedRows < lines)
                delete array[allocatedRows];
            delete array;
            throw;
        }

Two thing to note in code above:
1) allocatedRows is not decremented in [] operator, as behaviour would be undefined
2) After allocating array of pointers, dereferencing array elemnts has undefined behaviour(just like normal pointer without assignment). Please also keep in mind that in case above I didn't recovered from bad_alloc I just rethrowed, It can be logged somewhere else before call to termination. If You would like to create array of pointers from other user defined objects You could use std::uninitialized_copy or std::uninitialized_fill. Another way would be just to use vectors.

Upvotes: 0

AnatolyS
AnatolyS

Reputation: 4319

Use a linear representation of 2d array:

std::unique_ptr<int[]> array(new int[rowCount*colCount]);

for (size_t r = 0; r < rowCount; r++)
  for (size_t c = 0; c < colCount; c++)
    (array.get())[r*colCount + c] = r*c;

Upvotes: 0

Vishal
Vishal

Reputation: 158

I would not recommend you writing this type of code, but if you still want to hack your way out you can do something like this:-

int main()
{
Block*** grid;      

grid = new Block**[10];         
for(int i = 0 ; i < 10 ; i++)
{       
    grid[i] = new Block*[10];   
}

/*Here, we have created a grid of pointers*/

/*

|Block**[10]|

|Block[0] **|------------->|Block* [10]|
|Block[1] **|------------->|Block* [10]|
|Block[2] **|------------->|Block* [10]|
|Block[3] **|------------->|Block* [10]|
..
..
|Block[9] **|------------->|Block* [10]|

*/

for(int i = 0 ; i < 10 ; i++)
{       
    for(int j = 0 ; j < 10 ; j++)
    {
        grid[i][j] = new Block[10]; 
    }
}

/*

|Block**[10]|

|Block[0] **|------------->|Block* [0]|------------->|Block1|Block2| .. |Block10|
                           |Block* [1]|------------->|Block1|Block2| .. |Block10|
                           |Block* [2]|------------->|Block1|Block2| .. |Block10|
                           ..
                           |Block* [9]|------------->|Block1|Block2| .. |Block10|


|Block[1] **|------------->|Block* [0]|------------->|Block1|Block2| .. |Block10|
                           |Block* [1]|------------->|Block1|Block2| .. |Block10|
                           |Block* [2]|------------->|Block1|Block2| .. |Block10|
                           ..
                           |Block* [9]|------------->|Block1|Block2| .. |Block10|          
|Block[2] **|
|Block[3] **|
..
..
|Block[9] **|

*/
 }

Upvotes: 2

Stefano
Stefano

Reputation: 4031

A dynamic 2D array is an array of pointers to arrays. You should initialize first the array of pointer, then the others array using a loop.

Here an example using int that creates an array[rowCount][colCount]:

int** array = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
    array[i] = new int[colCount];

otherwise of course you can always have a 2D array on the stack by using:

int array[rowCount][colCount];

Upvotes: 1

Related Questions