提问者:小点点

删除没有虚拟析构函数的基类指针会导致内存泄漏吗?


这是一个解释虚拟析构函数的例子。(见http://www.geeksforgeeks.org/g-fact-37/)我根据这个例子修改了代码,并且有一个关于内存泄漏的问题。

假设基类有一个变量int num,派生类有一个浮动货币变量。

deletebase_ptr;被调用时,由于基类的析构函数是虚拟的,所以应该先调用~导出(),然后再调用~Base()

我的问题是“函数删除是否足够智能,以便它可以释放为int num(基类)和浮动货币(派生类)分配的内存?

我认为base_ptr是Base*类型的指针,所以它可能只释放Base类所需的内存量。然而,似乎即使base_ptr是指向Base类的类型,int和flod都会被释放。如果是这样,如果我们将~Base()设为非虚析构函数,会导致内存泄漏吗?使用~Base()的非虚析构函数,我们会错过~Derive()的调用。因为在基类和派生类中没有动态分配任何东西,所以~Derive()实际上根本没有释放任何内存,并且delete的函数将释放int num浮钱的内存。

#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个答案

匿名用户

你所描述的是未定义行为,这意味着任何讨厌的东西都可能出错,而不仅仅是内存泄漏。

但在实践中,如果继承不是虚的,派生类没有其他基类,派生类没有带有非平凡析构函数的成员,你可能会得到调用Base::~Base()析构函数,然后在指针上调用操作符删除操作符删除(void*)函数只是接受一个指针并释放它指向的所有内存,所以那里没有“内存泄漏”。