【发布时间】:2017-08-08 06:36:49
【问题描述】:
这里是一个解释虚拟析构函数的例子。(见http://www.geeksforgeeks.org/g-fact-37/) 我根据那个例子修改了代码,有一个关于内存泄漏的问题。
假设 Base 类有一个 int num 变量,Derived 类有一个 float money 变量。
在调用delete base_ptr;时,由于基类的析构函数是虚函数,所以应该先调用~derived(),再调用~Base()。
我的问题是“函数 delete 是否足够聪明,以至于它可以释放分配给 int num(Base Class) 和 float money(Derived Class) 的内存?
我认为 base_ptr 是 Base* 类型的指针,因此它可能只会释放 Base 类所需的内存量。但是,即使 base_ptr 指向 Base 类的类型,似乎 int 和 float 也会被释放。如果是这样的话,如果我们将~Base()设为非虚拟析构函数会导致内存泄漏吗?使用~Base() 的非虚拟析构函数,我们将错过~Derived() 的调用。因为在基类和派生类“内”没有动态分配任何内容,看来~Derived() 实际上根本没有释放任何内存,delete 的函数将释放int num 和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;
}
【问题讨论】:
-
这段代码很好,但如果 Base 析构函数不是虚拟的,那将是未定义的行为
-
首先,如果没有虚拟析构函数,代码将具有未定义的行为,并且没有必要讨论隐形独角兽的颜色。其次,在询问程序是否会“只释放一部分内存”之前,请考虑您如何使用
malloc和free,并问自己如何告诉free您想要释放多少内存. -
C++ 标准明确指出,通过基类指针删除派生类实例是未定义的行为。试图弄清楚什么时候可以“愚弄系统”似乎不值得。
标签: c++ memory-leaks virtual-destructor