不匹配的删除不再是未定义的行为?

时间:2016-10-12 07:13:17

标签: c++ language-lawyer dynamic-memory-allocation delete-operator c++17

我注意到C++ drafte51a2152不再包含以下措辞:

  

如果标准库中提供给operator delete(void*)的值不是标准库中先前调用operator new(std::size_t)operator new(std::size_t, const std::nothrow_t&)返回的值之一,则行为未定义,如果标准库中提供给operator delete[](void*)的值不是先前在标准库中调用operator new[](std::size_t)operator new[](std::size_t, const std::nothrow_t&)返回的值之一,则行为未定义。

这是否意味着像

这样的代码
int * const p = new int[42];
delete p; // instead of delete[] p;

将不再有未定义的行为,或者我错过了什么?

2 个答案:

答案 0 :(得分:4)

无论如何,该段处理分配/解除分配功能。不匹配的new / delete表达式在[expr.delete]/2中处理,并保持不变:

  

在第一个替代(删除对象)中,操作数的值   delete可以是空指针值,指向非数组对象的指针   由先前的 new-expression 创建,或者是指向子对象的指针   ([intro.object])表示这样一个对象的基类(Clause   [class.derived])。如果不是,则行为未定义。在第二   替代(删除数组),删除操作数的值可能是   空指针值或由前一个引起的指针值   array new-expression 82 如果没有,则行为未定义。

答案 1 :(得分:1)

措辞已简单地移至operator delete

的说明中
  

[new.delete.single]/12:要求:ptr应为空指针或其值应表示先前调用(可能已替换)operator new(std::size_t)或{所分配的内存块的地址{1}}未通过对operator new(std::size_t, std::align_val_t)的干预调用而失效。

有关GitHub仓库中的更改,请参阅here。阵列版本有类似的措辞。没有任何改变在语义上,它只是它在标准中表达的方式。