Question

I'm having trouble understanding how to use dynamic allocation with constructors.

I use in my code a class named graph (which is just a bool 2-d matrix representing the edges between the nodes) with the following constructor/destructor (there others methods, but I dont think it's relevant here) :

class graph{

private:
bool** edges;
int size;

public:
graph(int size = 0):size(size){
    edges = new bool*[size];
    for (int i = 0; i < size; i++){
        edges[i] = new bool[size];
    }
}

~graph(){
    for(int i = 0; i < size; ++i) {
        delete [] edges[i];
    }
    delete [] edges;
}

//others methods

};

In my main, I want to use dynamic allocation :

int main()
{

    int size;
    cout << "Enter graph size :" << endl;
    cin >> size;

    graph g1 = new graph(size);

    //some processing code

    return 0;
}

Howewer, I get an error on the instantiation (ie new graph(size) ) :

invalid conversion from 'graph*' to 'int' [-fpermissive]

I don't really get what is going wrong, and I'm pretty sure it's a syntax I have already seen in others places.

Actually, I dont really get how memory allocation works with the creation of object.

Here, I use new in my constructor to create the bool 2d-matrix, so it's going to the heap, no ? But if I instanciate the object using the following static instruction : graph g1(const_size);

Then it's not suppose to going to the stack ?

Thank you in advance for your answers.

EDIT

Just one last question :

graph *g1 = new graph(size);

is storing g1 (pointer) on stack, but the object is created on the heap.

graph g1(size);

is creating object on the stack, and g1 is a reference to it.

But in any case, the matrix edges would be on the heap ? Or in the second case it would somehow end on the stack ?

Was it helpful?

Solution

The error is here:

graph g1 = new graph(size);

This should be:

graph *g1 = new graph(size);

The reason is following:

new graph(size)

is creating new graph object and it is returning a pointer to it (with graph* type), and:

graph g1 = ... 

is trying to convert that to object to int (in order to call graph(int) constructor) - so the error is invalid conversion from 'graph*' to 'int'.

Now, I suppose this is some kind of exercise, as you shouldn't use allocation on heap in this example. But if you use it anyway, don't ever forget:

delete g1;

Actually, I dont really get how memory allocation works with the creation of object.

graph *g1 = new graph(size);

is storing g1 (pointer) on stack, but the object is created on the heap.

graph g1(size);

is creating object on the stack, and g1 is a reference to it.

P.S. Avoid this:

 graph g1 = graph(const_size);

This will first create evaluate right side of the statement and it will temporary graph object, and it will use copy-constructor to initialize g1.

But for example, if I want a program who can deal with various graph size, without recompiling it each time I want to work with a different size, I would need something like that, no ?

No, you can use stack allocation for this (I've just noticed that in your example, you're using const_size - parameter to the constructor of object allocated on stack doesn't need to be constant):

int size;
std::cout << "Enter size: ";
std::cin >> size;
graph g1(size);

Yes, dynamic allocation is not needed here, I just did that code to practice myself. But it would be necessary if I wanted to work with various sized graph without recompiling, no ?

No, look at the example right above this - stack allocated object with variable size - without recompiling.

I thought we were not supposed to call the destructor ourselves and that it was going to be called anyway when we go out of scope ? (I even read that it was actually bad to call it in some cases, as it might be calling it a second time)

That's true in case of stack allocated objects - the destructor will be called at the end of the scope. However, if you allocate object on heap, the destructor is not called until you call delete.

But in any case, the matrix edges would be on the heap ?

    edges = new bool*[size];
    for (int i = 0; i < size; i++){
        edges[i] = new bool[size];
    }

Yes, the entire matrix is allocated on heap.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top