nrocha
nrocha

Reputation: 394

Using private vars to initialize array

I'm trying to do a little application that would calculate some paths for a given graph.

I've created a class to handle simple graphs, as follows:

class SimpleGraph {

    int _nbNodes;
    int _nbLines;

   protected:
    int AdjMatrix[_nbNodes, _nbNodes]; //Error happens here...
    int IncMatrix[_nbNodes, _nbLines]; //...and here!


   public:
    SimpleGraph(int nbNodes, int nbLines) { this->_nbNodes = nbNodes - 1; this->_nbLines = nbLines - 1; };
    virtual bool isSimple();
};

At compilation time, I get an error on the two protected members declaration.

I don't understand what is wrong, as there is only one constructor that takes these values as parameters. As such, they cannot be uninitialized.

What am I missing here?

Upvotes: 1

Views: 73

Answers (3)

didierc
didierc

Reputation: 14750

In the lines

int AdjMatrix[_nbNodes, _nbNodes]; //Error happens here...
int IncMatrix[_nbNodes, _nbLines]; //...and here!

The array notation is wrong. You cannot specify a 2 dimensional array that way in C++. The correct notation uses brackets on each dimension, as for instance:

int data[5][2];

Regarding the problem you are facing, the dimensions of an array in C++ must be specified at compile time, ie. the compiler must know what are the values used to indicate the array dimension when compiling the program. This is clearly not the case here. You must revert to use integer literals, as in my example, or change the code to use vectors:

std::vector<std::vector<int> > AdjMatrix;

and in the constructor:

SimpleGraph(int nbNodes, int nbLines) : AdjMatrix(nbNodes) {
    for (int i = 0; i< nbNodes; i++)
        AdjMatrix[i].resize(20);
}

Note that you won't need _nbNodes anymore, and use instead the size() method on AdjMatrix. You will have to do the same for IncMatrix.

Another option, if you know the values at compile time, is to use macros to define them symbolically.

#define NBNODES  20

int AdjMatrix[NBNODES][NBNODES];

but since you wish to pass them as constructor parameter, this may not fit your need. Still, if you know that the parameters are constants at compile time, you might be able use the C++11 constexpr qualifier on the constructor parameters.

Upvotes: 1

Oswald
Oswald

Reputation: 31685

Objects in C++ have a fixed size that needs to be known at compilation time. The size of AdjMatrix and InMatrix are not known at compilation time, only at run time.

Upvotes: 2

Tushar
Tushar

Reputation: 8049

The compiler needs to know how much space to allocate for a member of class SimpleGraph. However, since AdjMatrix and IncMatrix are defined on the stack and their sizes are determined at run-time (i.e., after compilation), it cannot do that. Specifically, the standard says that the size of an array in a class must be a constexpr.

To fix this, you can:

  • Allocate AdjMatrix and IncMatrix on the heap instead and then you can allocate memory at runtime.
  • Use a fixed size for the two arrays and keep them on the stack.

--

Another major issue with your code is that you cannot create multi-dimensional arrays using a comma (AdjMatrix[int, int]). You must instead either use:

  • AdjMatrix[int][int]
  • AdjMatrix[int * int]

Upvotes: 3

Related Questions