29

我知道delete空指针是无操作的:

在任一替代方案中,如果 delete 的操作数的值是空指针,则该操作无效。
(C++ 标准5.3.5 [expr.delete] p2

而且删除void*指针是未定义的行为,因为无法调用析构函数,因为没有类型的对象void

在第一种delete object选择如果不是,则行为未定义。
(C++ 标准5.3.5 [expr.delete] p2

现在,通常我认为首先列出的内容会覆盖稍后列出的内容,但是void*下面的空指针呢?

void* p = 0;
delete p; // UB or well-defined?
4

3 回答 3

13

我想知道您如何才能达到仅在指针为空时才删除指针的情况。但停留在语言律师模式...

在 C++ 03 中

5.3.5/1

delete 的操作数应具有指针类型或具有单次转换为指针类型的类类型。

void* 是指针类型,因此空指针满足静态要求。

5.3.5/2

在任一备选 [deletedelete[]] 中,如果 delete 的操作数的值是空指针,则该操作无效。

这给出了想要的行为。

5.3.5/3

在第一种选择(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义.

这不相关,空指针不引用要检查附加约束的对象。

在 C++ 0X 中

5.3.5/1

操作数应具有指向对象类型的指针,或具有指向对象类型指针的单个非显式转换函数(12.3.2)的类类型。

void* 不是指向对象类型的指针,因此应该被拒绝。

于 2011-05-30T14:08:00.533 回答
8

§5.3.5/3 说,

在第一种选择(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义. 在第二种选择(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义73

在脚注中说,

73 -这意味着不能使用 void* 类型的指针删除对象,因为没有 void 类型的对象。

所以,是的,它的UB。

现在一旦它进入行为不明的城市,它是否为空都无关紧要,因为它的行为不能精确地保持良好定义,因为它已经在行为不明的城市中获得了住所。


编辑:

得到了另一个主题,它也引用了相同的内容并说它的 UB:

删除空指针是否安全?

于 2011-05-30T04:33:29.007 回答
2

我相信它未定义的行为。new void是不允许的(你不能创建 type 的对象void),所以调用deleteavoid*也不应该有意义。它是否指向NULL并不重要。我永远不会在我的代码中的任何地方使用这样的东西。

于 2011-05-30T04:32:04.360 回答