我注意到C++ draft的e51a2152不再包含以下措辞:
如果标准库中提供给
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;
将不再有未定义的行为,或者我错过了什么?
答案 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。阵列版本有类似的措辞。没有任何改变在语义上,它只是它在标准中表达的方式。