这是未定义的行为与否

Is this undefined behavior or not?

本文关键字:未定义      更新时间:2023-10-16
class A
{
public:
    int i;
    ~A()
    {   
        std::cout << "~A" << std::endl;
    }   
};
class B: public A
{
public:
    int k;
    ~B()
    {   
        std::cout << "~B" << std::endl;
    }   
};
int main(int argc, char* argv[])
{
    A* p = new B();
    delete p;
    return 0;
}

以上不会导致内存泄漏,尽管基本析构函数不是虚拟的,我知道原因。

但这种未定义的行为与否?

假设派生类不指向其他动态数据,即使基析构函数是非虚拟的,也不会有内存泄漏?

是的。通过指向没有virtual析构函数的基类的指针删除派生class的对象是教科书 UB。

5.3.5/3:

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

因为它是未定义的行为,所以猜测代码是否会泄漏是没有意义的。只需尝试修复代码而不是预测结果。

是的,因为静态类型(这里是A)与动态类型(在您的示例中B)不同,并且没有virtual析构函数,它是一个 UB。

5.3.5/

2(5.3.5/3 英寸C++11):

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