n3242 の 5.3.5 [expr.delete] から:
2
[...]
2 番目の選択肢 ( delete array ) では、delete のオペランドの値は、null ポインター値または前の配列 new-expression から得られたポインター値である可能性があります。そうでない場合、動作は未定義です。[...]
つまり、 forは何かの形式(新しい式) または 0の結果delete[] p
である必要があります。 の結果がここにリストされていないので、最初のケースは正しいと思います。p
new[] p
operator new
2番目のケースは大丈夫だと思います。18.6.1.2 [new.delete.array] から:
11
void operator delete[](void* ptr) noexcept;
[...]
必須: ptr は null ポインターであるか、その値は、以前の 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] で、ジェリーが警告していることの規範的なテキストを追跡したと思います。
10
new 式は、要求されたスペースの量を std::size_t 型の最初の引数として割り当て関数に渡します。その引数は、作成されるオブジェクトのサイズ以上でなければなりません。オブジェクトが配列の場合にのみ、作成されるオブジェクトのサイズよりも大きくなることがあります。[...]
同じ段落に続くのは、実装の新しい式が実際に配列が占めるスペースよりも多くを割り当て関数から自由に要求できることを強調する例です (非規範的) (std::size_t
割り当て解除関数で使用可能なオプションのパラメーターを格納する心)、結果にオフセットできること。したがって、アレイの場合はすべての賭けが無効になります。ただし、非配列の場合は問題ないようです。
auto* p = new T;
// Still icky
p->~T();
operator delete(p);