简体   繁体   中英

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!

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] **|

*/
 }

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

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;

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.

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