为什么删除[]带有基指针的派生对象数组是未定义的行为?
C 标准的 5.3.5 [ expr.delete] 指出,在“删除数组”的情况下,如果要删除的对象的动态类型与其静态类型不同,则会发生未定义的行为。这意味着以下代码片段会调用未定义的行为:
<code class="cpp">struct B { virtual ~B() {} }; struct D : B {}; B* p = new D[20]; delete [] p; // undefined behavior</code>
未定义行为的基本原理
“删除 []”操作需要指向第一个元素的指针一个数组的。但是,当使用指向派生对象数组的基指针时,该指针实际上引用第一个元素的基子对象。因此,“delete []”操作将尝试删除基本子对象而不是数组的第一个元素,这是不正确的。
在这种情况下强制执行正确的行为将涉及检索数组并执行动态转换为该类型。然而,这会给每个多态数组带来不必要的开销,即使不使用多态性也是如此。
此外,指针“p”本身的用途有限,因为它只指向基子对象。诸如“p[i]”(对于 i > 0)之类的常见数组操作是不可能的。
结论
“delete [] 的未定义行为“使用指向派生对象数组的基指针是一个有意识的设计决策,它:
以上是为什么删除带有基指针的派生对象数组被视为 C 中的未定义行为?的详细内容。更多信息请关注PHP中文网其他相关文章!