【问题标题】:delete'ing pointer of Type A pointing to pointer of type B删除 A 类型指针,指向 B 类型指针
【发布时间】:2011-09-14 11:17:36
【问题描述】:

假设我有一个 ABC* 类型的指针和另一个 XYZ* 类型的指针,它们都派生自一个公共父类。

如果我通过显式转换将 XYZ* 分配给 ABC*,那么如果我调用

会发生什么

删除 abc; // abc 是 XYZ* 类型的

我会得到任何异常还是可以正常工作?

我已经尝试了上面的代码,它没有崩溃。那么谁能告诉我在什么情况下会删除抛出异常/故障/崩溃等?

删除指针会导致程序崩溃的情况有哪些?如果它们都定义了自定义析构函数,它们会崩溃吗

编辑:这是我的测试代码,没有任何崩溃

class ABC
{
public:
    int a;
    int b;
    int c;
};

class XYZ
{
public:
    double a;
    double b;
    double c;
};

int main()
{
    ABC* abc = new ABC();
    XYZ* xyz = (XYZ*)abc;

    delete xyz;

    return 0;
}

P.S:我在 Windows 平台上,如果有帮助的话。

EDIT2:好的,所以在读数之后,我将我的问题更改为,何时删除指针会导致崩溃(不包括未定义的行为)?

EDIT3: 调用 delete 时会发生什么?将调用谁的析构函数?

【问题讨论】:

  • 未定义的行为是导致崩溃的一种可能原因,无论是立即还是有时稍后。或者它可能看起来仍然有效!

标签: c++ pointers delete-operator


【解决方案1】:

这是非法的。如果在非数组删除表达式中要删除的指针的类型与要删除的对象的动态类型不同,则指向的对象的类型必须是要删除的对象的基类删除并且基类必须有一个虚析构函数。

参见 ISO/IEC 14882:2003 5.3.5 [expr.delete]/2。

【讨论】:

  • 能否强调一下
  • 是的,不知何故。谢谢。
【解决方案2】:

您的代码将表现出未定义的行为。请注意,这并不意味着它会崩溃,只是在您执行删除后它将处于未定义状态。认为 UB 总是会导致崩溃(如果是这样就好了)的想法是错误的。

【讨论】:

    【解决方案3】:

    如果我通过显式转换将 XYZ* 分配给 ABC*

    如果 XYZ 不是 ABC 的子类,那么这种显式转换,无论是通过 reinterpret_cast 还是 C 样式转换,都是未定义的行为。有时你会很幸运,即使程序有未定义的行为,它也会正常工作。不要计算你的幸运星,也不要故意调用未定义的行为。

    【讨论】:

    • 只是一点点,但演员表本身并不是未定义的行为。然而,对结果指针的任何取消引用都是未定义的行为。
    【解决方案4】:

    如果 XYZ 不是从 ABC 派生的,那么您不应该将前者的对象转换为后者 - 无论您的删除是否有效是无关紧要的。

    【讨论】:

    • 我知道,但我正试图找出崩溃的原因,我认为这可能是问题所在。这就是为什么我要问何时删除指针会导致崩溃?有无限的情况吗?
    • @Tux:UB 的问题在于它是未定义的,这反过来意味着你不能真正争论它,这意味着你不能在这种特殊情况下争论它,因为你没有提供(AFAIK)两个确切的对象,或者编译器版本和选项......如果代码正在转换不相关的对象,那是一个需要修复的错误,修复它并移至下一个错误。是的,对于某些编译标志,这可能是导致崩溃的原因(使用某些选项 VS 会用位模式覆盖已删除的内存,这可能会导致缓冲区溢出)
    猜你喜欢
    • 2011-08-02
    • 2015-04-06
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    相关资源
    最近更新 更多