Would it lead to memory leak when delete base clas

2019-09-20 07:11发布

问题:

Here is an example for explaining virtual destructor.(see http://www.geeksforgeeks.org/g-fact-37/) I modify the code based on that example, and have a question about memory leak.

Suppose Base class has a variable of int num, Derived class has variable of float money.

When delete base_ptr;is called, since destructor of base class is virtual, ~derived() should be called first and then ~Base().

My question is "can function delete is smart enough so that it would free the memory allocated for both int num(Base Class) and float money(Derived Class)?

I think base_ptr is the pointer of type Base*, so it might only free the amount of memory needed for Base class. However, it seems that both int and float would be freed even if base_ptr is pointing type of Base class. If it is the case, would it lead to memory leak if we make ~Base() a non-virtual destructor? With a non-virtual destructor of ~Base(), we would miss the call of ~Derived(). Because nothing is dynamically allocated "within" both Base Class and Derived Class, it seems that ~Derived() does not actually free any memory at all, and function of delete would free both memory of int num and float money.

#include <iostream>
using namespace std;

class Base {
public:
    int num;

 Base(int n):num(n){
    cout<<"Base::Constructor\n";
 }
    virtual ~Base(){
    cout<<"Base::Destructor\n";
 }
};

class Derived : public Base {
private:
  float money;
public:
 Derived(int n, float m):Base(n),money(m){
    cout<<"Derived::Constructor\n";
 }
 ~Derived(){
    cout<<"Derived::destructor\n";
 }
};



int main() {
    Base *base_ptr = new Derived(1,200.0);
    delete base_ptr;
    return 0;
}

回答1:

What you are describing is Undefined Behavior, which means any nasty stuff could go wrong, not just memory leaks.

But in practice, if the inheritance is not virtual, the derived class has no other base classes, and the derived class has no members with non-trivial destructors, you'll probably get the Base::~Base() destructor invoked and then operator delete called on the pointer. The operator delete(void*) function just takes a pointer and frees up all the memory it pointed at, so no "memory leak" there.