簡単なテストアプリ:
cout << new int[0] << endl;
出力:
0x876c0b8
そのため、機能しているように見えます。これについて規格は何と言っていますか?空のメモリブロックを「割り当てる」ことは常に合法ですか?
5.3.4/7から
Direct-new-declaratorの式の値がゼロの場合、要素なしで配列を割り当てるために、割り当て関数が呼び出されます。
3.7.3.1/2から
サイズ0の要求として返されるポインターの逆参照の効果は定義されていません。
また
[by new]で要求されたスペースのサイズがゼロであっても、要求は失敗する可能性があります。
つまり、それを行うことはできますが、合法的に(すべてのプラットフォームで明確に定義された方法で)取得したメモリを逆参照することはできません-配列削除にのみ渡すことができます-そして削除する必要があります。
3.7.3.1/2の文に添付されている興味深い脚注(つまり、標準の規範的な部分ではなく、説明目的で含まれています)を示します。
[32。目的は、malloc()またはcalloc()を呼び出すことにより、演算子new()を実装できるようにすることです。したがって、ルールは実質的に同じです。 C++は、Null以外のポインターを返すためにゼロ要求を要求する点でCと異なります。]
はい、このようなゼロサイズの配列を割り当てることは合法です。ただし、それも削除する必要があります。
これについて規格は何と言っていますか?空のメモリブロックを「割り当てる」ことは常に合法ですか?
すべてのオブジェクトには一意のID、つまり一意のアドレスがあり、これはゼロ以外の長さを意味します(ゼロバイトを要求すると、実際のメモリ量は静かに増加します)。
これらのオブジェクトを複数割り当てた場合、異なるアドレスを持っていることに気付くでしょう。
はい、0
サイズのブロックをnew
で割り当てることは完全に合法です。アクセスできる有効なデータがないため、単に有用な操作を行うことはできません。 int[0] = 5;
は違法です。
ただし、標準ではmalloc(0)
のようなものがNULL
を返すことが許可されていると思います。
delete []
割り当てから戻されるポインターも同様に必要です。
興味深いことに、C++では、ゼロバイトが要求された場合でも、演算子newが正当なポインターを返す必要があります。 (この奇妙な響きの振る舞いを必要とすることで、言語の他の部分が単純化されます。)
Effective C++ Third Editionは、「項目51:新規作成および削除時の規約に従う」でこのように述べています。