Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

2D Array of Object pointers in C++

How do you allocate a 2D array of pointers to objects?

Currently I have:

file.h

extern ClassName **c;

file.cpp

ClassName **c;
int main(){
    // some stuff
    c = new ClassName*[sizex];
    for(int i = 0; i < sizex; ++i){
        c[i] = new ClassName[sizey];
    }

    for(int i = 0; i < sizex; ++i){
        for(int j = 0; j < sizey; ++j){
            c[i][j] = new ClassName();
        }
    }

Which fails to compile with error's stating that there is no match for operator= using ClassName and ClassName*, which looking at the error makes sense. But if I were to change the assignment of c[i][j] to

ClassName cn();
c[i][j] = cn;

It gives a plethora of other errors. The array's size cannot be known until runtime (read from stdin) and it must also be extern. What is the proper way to declare an array in this case?

like image 776
btcraig Avatar asked Dec 15 '22 17:12

btcraig


2 Answers

You have to declare the pointer like

extern ClassName ***c;

The allocation will look like

c = new ClassName**[sizex];
for(int i = 0; i < sizex; ++i){
    c[i] = new ClassName*[sizey];

    for(int j = 0; j < sizey; ++j){
        c[i][j] = new ClassName();
    }
}

You could define the 2D array correctly yourself if you would declare the array of some abstract type T. Then all you need is to change T to ClassName *

As for this declaration

ClassName cn();

then it declares a function that has return type ClassName and has no parameters.

like image 162
Vlad from Moscow Avatar answered Dec 27 '22 06:12

Vlad from Moscow


ClassName *p1;

p1 can point to one ClassName or an array of ClassNames.

ClassName **p2;

p2 can point to one ClassName* or an array of ClassName*s.

*p2 can point to one ClassName or an array of ClassNames.

When you use:

   c[i] = new ClassName[sizey];

you are allocating memory so that c[i][j] can hold a ClassName but not a ClassName*.

If c[i][j] = ClassName(); is failing, and you want to use c[i][j] = new ClassName();, then c has to be declared as:

 ClassName*** c;

However, in stead of doing that, I strongly suggest use of std::vector and a smart pointer.

 std::vector<std::vector<std::unique_ptr<ClassName>>> c;
like image 32
R Sahu Avatar answered Dec 27 '22 06:12

R Sahu