删除null void *指针是不确定的行为?

时间:2011-05-30 04:16:39

标签: c++ undefined-behavior void-pointers language-lawyer null-pointer

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

  

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

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

  

在第一个备选方案(delete object)中,delete的操作数的值应为指向非数组对象的指针或指向表示此类基类的子对象的指针对象。如果不是,则行为未定义   (C ++ Standard 5.3.5 [expr.delete] p2

现在,通常我认为列出的内容首先列出了后面列出的内容,但是如下所示null void*指针呢?

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

3 个答案:

答案 0 :(得分:12)

我想知道如何只有在指针为空时才能删除指针。但保持语言律师模式......

在C ++ 03

5.3.5 / 1

  

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

void *是一个指针类型,因此null void指针符合静态要求。

5.3.5 / 2

  

在替代[deletedelete[]]中,如果delete操作数的值为空指针,则操作无效。

这给出了想要的行为。

5.3.5 / 3

  

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

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

在C ++ 0X

5.3.5 / 1

  

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

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

答案 1 :(得分:8)

§5.3.5/ 3说,

  

在第一种选择中(删除   对象),如果是静态类型的   操作数与其动态不同   类型,静态类型应为基础   操作数的动态类型的类   而静态类型应该有一个   虚拟析构函数或行为是   未定义。在第二种选择   (删除数组)如果动态类型   要删除的对象不同于   它的静态类型,行为是   未定义 73

在脚注中说,

  

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

所以是的,它的UB。

现在一旦它进入未定义行为的城市,它是否为空无关紧要,因为它的行为不能保持精确定义,因为它已经 在这个未定义行为的城市居住。


编辑:

得到了另一个引用相同的主题并说出它的UB:

Is it safe to delete a void pointer?

答案 2 :(得分:2)

我相信它未定义的行为。不允许new void(不允许您创建void类型的对象),因此在delete上调用void*也没有意义。它是否指向NULL并不重要。我永远不会在我的代码中使用这样的东西。