Search code examples
c++inheritancememory-managementvirtual

Memory location for virtual functions


Assuming I have the base.h class

#ifndef BASE_H
#define BASE_H

class base
{
public:
    base(){}
    virtual void id() const{ std::cout << "base\n"; }
    virtual ~base(){}
protected:
private:
};

#endif // BASE_H

and the derived.h class

#ifndef DERIVED_H
#define DERIVED_H

#include <base.h>

class derived : public base
{
public:
    derived(){}
    void id() const{ std::cout << "derived\n"; }
protected:
private:
};

#endif // DERIVED_H

I started testing different outcomes having this code in the main

int main()
{
    base* bas;
    derived* der;
    base statbas;
    derived statder;

    *bas = statbas;   // here it crashes

    bas = new base;   

    *bas=statbas;     // here it works. It also worked with bas=&statbas;

    bas->id();

    return 0;
}

It seems that I need to allocate some memory for the pointer bas otherwise the program will crash. This thing confuses me mainly because I cannot imagine to store memory for an object (bas in this case) that does not have any variables (the class base is formed just by functions).

Another thing that confuses me it's that apparently *bas=statbas (bas points to statbas) and bas=&statbas (bas has the memory address of statbas) are not equal, in fact the first makes the program to crash while the second works.

I assume all these issues are connected to the function which is virtual in the base class, indeed when id() is not declared as virtual the program does not crash (but obviously does not work correctly either).

Can someone clear my mind about how the memory is managed in this case?


Solution

  • *bas = statbas;   // here it crashes
    

    Because you dereference bas which is uninitialized and thus you get undefined behaviour.

    bas = new base;
    *bas=statbas;     // here it works. It also worked with bas=&statbas;
    

    It works because bas was initialized on previous row and points to a valid object in memory.bas=&statbas does something else. It assigns the bas to point to another object, causing the newly allocated object to leak because it's no longer pointed to by anything and therefore can never be deleted.

    It seems that I need to allocate some memory for the pointer bas otherwise the program will crash.

    Correct.

    This thing confuses me mainly because I cannot imagine to store memory for an object (bas in this case) that does not have any variables (the class base is formed just by functions).

    You can allocate memory for objects that have no members in exactly the same way as you do for objects that do have members.

    Another thing that confuses me it's that apparently *bas=statbas (bas points to statbas) and bas=&statbas (bas has the memory address of statbas) are not equal, in fact the first makes the program to crash while the second works.

    That's not what the first one does. The first one dereferences bas and then copies statbas to the dereferenced object. The second one sets bas to point to statbas.

    I assume all these issues are connected to the function which is virtual in the base class, indeed when id is not declared as virtual the program does not crash (but obviously does not work correctly either).

    Nope, the issue is not really connected to the virtual function. You simply dereference an uninitialized pointer. The virtuality happens to be something that luckily caused the undefined behaviour to be different.