从 n3242 中的 5.3.5 [expr.delete] 开始:
2
[...]
在第二种选择(delete array)中,delete 的操作数的值可以是空指针值或由前一个数组 new 表达式产生的指针值。如果不是,则行为未定义。[...]
这意味着 for delete[] p
,p
一定是某种形式的结果new[] p
(一个新的表达式),或者 0。看到operator new
这里没有列出的结果,我认为第一种情况是正确的。
我相信第二种情况是好的。从 18.6.1.2 [new.delete.array] 开始:
11
void operator delete[](void* ptr) noexcept;
[...]
要求: ptr 应为空指针,或其值应为先前调用 operator new 或 operator new[](std::size_t,const std::nothrow_t&) 的返回值,该值未被干预调用无效运算符删除。[...]
(在 3.7.4.2 [basic.stc.dynamic.deallocation],第 3 段中有类似的文字)
因此,只要 de/allocation 函数匹配(例如delete[] (new[3] T)
格式正确),就不会发生任何不好的事情。[或者是吗?见下文 ]
我想我在 5.3.4 [expr.new] 中跟踪了 Jerry 警告的规范文本:
10
new 表达式将请求的空间量作为 std::size_t 类型的第一个参数传递给分配函数。该参数不应小于正在创建的对象的大小;只有当对象是一个数组时,它才可能大于正在创建的对象的大小。[...]
在同一段后面是一个示例(非常不规范),它强调实现的新表达式确实可以自由地从分配函数中询问比数组占用的空间更多的空间(存储std::size_t
可用于释放函数的可选参数)注意),并且它们可以抵消结果。所以在数组的情况下所有的赌注都没有了。不过,非数组情况似乎很好:
auto* p = new T;
// Still icky
p->~T();
operator delete(p);