【问题标题】:Deleting pointers after casting them with dynamic_cast: what happenes to the allocated memory在使用 dynamic_cast 强制转换后删除指针:分配的内存会发生什么
【发布时间】:2017-07-29 09:00:36
【问题描述】:

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

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 时,它工作正常。如果我们取消注释“delete p3”或删除“p4”,程序就会崩溃,我不知道为什么。我还观察到,如果我们取消注释前面提到的任何一个删除语句并注释“删除 p2”,代码就可以正常工作。

有人可以解释一下吗?谢谢!

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

【问题讨论】:

  • 为什么要这样做?你应该有虚拟析构函数
  • 不假思索... 一个 new多个 delete 绝对是一个错误。顺便说一句,只有在B 中至少有一个virtual 函数时,代码才应该编译。你应该使用虚拟析构函数
  • 请在删除任何内容之前使用调试器并打印指针的值。您的演员表无效,因此指针(不包括 p)应该为空。
  • @patatahooligan 删除 null 是个问题,所以这不是崩溃的原因
  • 必须对其进行调试和进一步调查,因为它不应该在那里崩溃。

标签: c++ pointers casting


【解决方案1】:

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

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

所以你的代码可能看起来可以工作,但它也是无效的。

【讨论】:

    猜你喜欢
    • 2021-08-24
    • 1970-01-01
    • 2019-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    相关资源
    最近更新 更多