c++ - 使用 dynamic_cast : what happenes to the allocated memory 强制转换后删除指针

标签 c++ pointers casting

假设我们有以下类层次结构:

class B{     
    B() { cout<<"B\n"; }
    ~B(){ cout<<"~B\n"; }    
};

class D1 : virtual public B {
    D1() { cout<<"D1\n"; }
    ~D1(){ cout<<"~D1\n"; }
};

class D2 : virtual public B {
    D2() { cout<<"D2\n"; }
    ~D2(){ cout<<"~D2\n"; }
};

class MM : public D1, public D2 {
    MM() { cout<<"MM\n"; }
    ~MM(){ cout<<"~MM\n"; }
};

int main(){
    B *p = new MM();
    D1 *p2 = dynamic_cast<D1*>(p);
    D2 *p3 = dynamic_cast<D2*>(p);
    MM *p4 = dynamic_cast<MM*>(p);
    //delete p4;
    //delete p3;
    delete p2;
    delete p;
    return 0;
}

我不太习惯 dynamic_cast 和从基类到派生类的指针,所以如果我错了请纠正我,但这基本上创建了一个 B* 类型的指针,指向一个 MM() 类型的对象。之后它创建另外两个指针,并使用 dynamic_cast 将 B* 指针转换为 D*、D2* 和 MM*。

现在让我担心的是:所有四个都指向同一个内存块(对吗?)。当我们删除 p2,然后删除 p 时,一切正常。如果我们取消注释“删除 p3”或删除“p4”,程序就会崩溃,我不知道为什么。我还观察到,如果我们取消注释前面提到的任何一个删除语句并注释“delete p2”,代码就可以正常工作。

有人愿意解释一下吗?谢谢!

PS:如果我们创建另一个指针并将前一个指针与 dynamic_cast 一起使用,分配的内存会发生什么情况,你们中的任何人都可以解释一下吗?谢谢!

最佳答案

通过其他类型删除类(没有虚拟析构函数)是未定义行为 (UB)。

两次删除指针也是未定义行为(UB)。

因此您的代码可能看起来有效,但它也是无效的。

关于c++ - 使用 dynamic_cast : what happenes to the allocated memory 强制转换后删除指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45387435/

相关文章:

c++ - 将非模板基类向下转换为模板化派生类 : is it possible?

c++ - Travis CI 与 Clang 3.4 和 C++11

c - 什么时候访问指向 "dead"对象的指针有效?

c# - InvalidCastException 尝试从装箱的 int 转换为可为 null 的枚举

c - 以下 C 中的声明之间有什么区别?

c - 为什么类型转换在指针的情况下不起作用?

从 uint8_t 指针转换为 uint32_t 整数编译错误

c++ - 需要帮助找出适合我的数据结构的语法

c++ - 检查 uint8_t[8] 是否包含任何非 0 并使用一次内存负载访问非零插槽

c++ - 使用着色器渲染时 OpenGL 纹理全黑