关于c ++:删除没有虚析构函数的基类指针会导致内存泄漏吗?

Would it lead to memory leak when delete base class pointer without virtual destructor?

下面是一个解释虚拟析构函数的示例。(请参阅http://www.geeksforgeks.org/g-fact-37/)我基于该示例修改了代码,并对内存泄漏提出了一个问题。

假设基类有一个int num变量,派生类有一个float money变量。

调用delete base_ptr;时,由于基类的析构函数是虚拟的,所以应该先调用~derived(),然后调用~Base()

我的问题是"函数delete是否足够智能,以便释放为int num(基类)和float money(派生类)分配的内存?"

我认为base ptr是base*类型的指针,因此它可能只释放基类所需的内存量。然而,似乎int和float都将被释放,即使base ptr指向基类的类型。如果是这样的话,如果我们使~Base()成为非虚拟析构函数,它会导致内存泄漏吗?如果使用~Base()的非虚拟析构函数,我们将错过~derived()的调用。由于基本类和派生类中没有动态分配的内容,因此似乎~derived()实际上根本没有释放任何内存,delete的函数将释放int numfloat money的内存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
using namespace std;

class Base {
public:
    int num;

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

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



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


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

但是在实践中,如果继承不是虚拟的,派生类没有其他的基类,并且派生类没有具有非平凡析构函数的成员,那么您可能会调用Base::~Base()析构函数,然后在指针上调用operator deleteoperator delete(void*)函数只接受一个指针并释放它指向的所有内存,因此没有"内存泄漏"。