假设我们有以下类层次结构:
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/