Search code examples
c++oopconstructorgarbage

Passing variable to constructor to a derived class gives garbage value, both the base and derived class's constructors have different parameters. Why?


The derived and base class's constructor both have different parameters.

When passing a variable to the constructor of the derived class, it is giving garbage value when declaring an array of base class. Array size is not 'n' but some garbage value.

class LinkedList{
public:
    Node* head;
    LinkedList()
    {
        cout << "c";
        head=NULL;          
    }
};
class hashing : public LinkedList{
public:
    int n;
    hashing(int num)
    {
        this->n=num;
    }
    LinkedList* l = new LinkedList[n];
    void iterateL()
    {
        for(int i=0; i<n; i++)
        {
             l[i].head=NULL;
             cout << i << endl;
        }
    }
};
int main() 
{
int n=7;
hashing op(n);
}

The loop inside hashing class is expected to run 7 times but after running 4 times it gives an error.


Solution

  • Okay, the problem is subtle here (to the point where I didn't see the issue at first).

    The problem is you're initializing using the value of n (this->n) during the in class member initialization.

    The problem is, in C++, those initializers are all run during member initialization, which is prior to the constructor body. Since you don't set the value of this->n until the constructor body, this->n isn't initialized at all

    In other words, what you have is the same as writing

    hasing(int num): l(new LinkedList[n]) {
       this->n = num;
    }
    

    This occurs because by default, all members are initialized in the order specified in the class, substituting default member initializers (the expression after the = in the class definition) as appropriate.

    There are several solutions:

    Using the member initializer

    hashing(int num): n(num),l(new LinkedList[n])
    {
    
    }
    

    Using the constructor body:

    hashing(int num)
    {
       this->n = num;
       this->l = new LinkedList[n];
    }
    

    In both of the above cases, I would not set the default member specifier. I would just declare the pointer.

    LinkedList* l; // No default member initializer
    

    Finally, I would make sure you properly handle destruction, and copy/move assignment.