Search code examples
c++memorydestructormultiple-inheritancevirtual-destructor

multiple inheritance destructor calling his own and parent destructor? c++


Hi I'm trying to create a derived class from a derived class. But I don't know how to solve this memory problem.

Class C in below exmaple calls both his own destructor and the B-destructor. But that's not what I want, since it messes up my memory.

Should I use another aproach or is there a solution to this?

class A {
public:
    virtual ~A() {}
};


class B : public A {
public:

    B() : A() {}
    virtual ~B() {std::cout << "B Destructor" << std::endl;}
};

class C : public B {

public:
    C() : B() {}
    ~C() {std::cout << "C Destructor" << std::endl;}
};

int main() {

    A *b = new B();
    A *c = new C();

    delete b;
    delete c;

    return 0;
}

output:

 ./a.out
 B Destructor
 C Destructor
 B Destructor

//edit Sorry seems like I actually posted a working example. Nevertheless in my real code (but I actually used the pattern from above example: I get the error

labrob(5254,0x7fff77789000) malloc: * error for object 0x7fe3dbc00030: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug Abort trap: 6

And when I remove the destructor of C I get a memory leak this error actually only appears using the C-type Robot

so I have 3 kinds of robots which can be instantiated multiple times on runtime and are pushed into a list of robots.

which solve a maze on different threads

in the end I am deleting the robots from the list with an iterator

on valgrind it says am deallocating to much memory so my thoughts the destructor call of both B and C are causing this.

in my main.cpp:

    // delete robots
    for (auto it = robots.begin(); it != robots.end(); ++it) {

        if(printSolution) std::cout << (*it)->solution() << std::endl;
        delete *it;

    }

    return 0;
}

Solution

  • I'm afraid the answer is that C++ is doing the right thing here. If this messes up your memory, you are doing the wrong thing. Unfortunately, without more context it is difficult to tell what wrong thing you are doing.

    When C inherits from B, ~B() should destroy memory owned by the B portion of C, and ~C() should handle any memory that is part of C, but not part of B.