虚拟分割器​​故障

ami*_*zle 2 c++ destructor

我在C++中有以下代码:

#include <iostream> 

class Number 
{ 
public: 
    virtual void foo(){std::cout << "Number foo\n";};
    Number (){ std::cout << "Number ctor" << std::endl;} 
    virtual ~Number(){ std::cout << "Number dtor" << std::endl;} 
}; 


class Complex : public Number 
{ 
public:
    virtual void foo(){std::cout << "Complex foo\n";};
    Complex (double r=0, double i=0) : _r (r), _i (i)
    { std::cout << "Complex ctor" << std::endl; };
    virtual ~Complex(){ std::cout << "Complex dtor" << std::endl;}
private: 
    double _r,_i;
};


int main()
{
    Number *numArr = new Complex [2];
    delete [] numArr;
    return 0; 
}
Run Code Online (Sandbox Code Playgroud)

当析构函数声明为虚拟时,应用程序将退出分段错误.当它没有被声明为虚拟时,会调用Number类析构函数(这很明显......).但是,当析构函数被声明为虚拟时,当我删除Complex类中的双精度时,没有分段错误,并且析构函数以预期的顺序(Complex,Number)被调用,所以我猜问题是相关的对于物体的大小,有人可以给我一个解释吗?谢谢,阿米特.

Naw*_*waz 6

Number *numArr = new Complex [2];
delete [] numArr;
Run Code Online (Sandbox Code Playgroud)

实际上,删除操作会调用未定义的行为.

§5.3.5/ 3说,

在第一个替代(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义.在第二个备选(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义.)

它的实际含义是:

Number *object= new Complex();
delete object; //well-defined

//BUT
Number *array = new Complex[N];
delete [] array; //undefined
Run Code Online (Sandbox Code Playgroud)