这是未定义的行为吗?

new*_*erl 0 c++ standards

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;
}
Run Code Online (Sandbox Code Playgroud)

虽然基础析构函数不是虚拟的,但上面不会导致内存泄漏,我知道原因.

但这是不确定的行为吗?

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

Luc*_*ore 7

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

5.3.5/3:

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

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