簡単なテストアプリ:
cout << new int[0] << endl;
出力:
0x876c0b8
したがって、動作するように見えます。これについて規格は何と言っていますか?空のメモリブロックを「割り当てる」ことは常に合法ですか?
簡単なテストアプリ:
cout << new int[0] << endl;
出力:
0x876c0b8
したがって、動作するように見えます。これについて規格は何と言っていますか?空のメモリブロックを「割り当てる」ことは常に合法ですか?
回答:
5.3.4 / 7から
direct-new-declaratorの式の値がゼロの場合、要素のない配列を割り当てるために割り当て関数が呼び出されます。
3.7.3.1/2から
サイズがゼロの要求として返されたポインタを逆参照した場合の影響は定義されていません。
また
[new by]によって要求されたスペースのサイズがゼロであっても、要求は失敗する可能性があります。
つまり、それを行うことはできますが、取得したメモリを合法的に(すべてのプラットフォームにわたって明確に定義された方法で)参照解除することはできません。配列の削除にのみ渡すことができます。削除する必要があります。
3.7.3.1/2の文に添付されている興味深い脚注(つまり、標準の規範的部分ではないが、説明の目的で含まれています)です。
[32。その意図は、malloc()またはcalloc()を呼び出すことによってオペレーターnew()を実装可能にすることです。したがって、ルールは実質的に同じです。C ++は、Null以外のポインタを返すためにゼロ要求を要求する点でCと異なります。]
new[]
とバランスをとらないと、メモリリークが発生する可能性がありますdelete[]
。特に、呼び出すときnew[i]
に、配列のサイズを格納するためにdelete[]
はい、このようなサイズ0の配列を割り当てることは合法です。ただし、それも削除する必要があります。
int ar[0];
違法であることを知っています。なぜ新しいものに問題がないのでしょうか。
sizeof (type)
決してゼロを返さないと予想されると思います。例を参照してください:stackoverflow.com/questions/2632021/can-sizeof-return-0-zero
これについて規格は何と言っていますか?空のメモリブロックを「割り当てる」ことは常に合法ですか?
すべてのオブジェクトには一意のID、つまり一意のアドレスがあり、これは長さがゼロ以外であることを意味します(実際のメモリ量は、ゼロバイトを要求した場合、暗黙的に増加します)。
これらのオブジェクトを複数割り当てた場合、それらは異なるアドレスを持っていることがわかります。
operator []
また、配列のサイズをどこかに保存します(isocpp.org/wiki/faq/freestore-mgmt#num-elems-in-new-arrayを参照)。したがって、実装がデータとともにバイトカウントを割り当てる場合、バイトカウントとデータ用に0バイトを割り当てるだけで、最後の1つ前のポインタを返すことができます。
operator new[]
は異なるポインターを返すはずです。ところで、にnew expression
はいくつかの追加ルールがあります(5.3.4)。new
サイズ0で実際に何かを割り当てる必要があるという手掛かりは見つかりませんでした。申し訳ありませんが、あなたの回答が質問に対する回答ではないことがわかりました。
new[]
、動的メモリがマップされていない範囲のアドレスを実装が返すため、実際にはメモリを使用しない(アドレス空間を使用している)
while(!exitRequested) { char *p = new char[0]; delete [] p; }
ポインターをリサイクルせずにループを実行しているコンピューターは、アドレス空間が不足する前に、ゴミになってしまうが、32ビットポインターを備えたプラットフォームでは、はるかに合理的な仮定。
はい、で0
サイズのブロックを割り当てることは完全に合法new
です。アクセスできる有効なデータがないため、これを使用して何も実行できません。int[0] = 5;
違法です。
しかし、私は基準がmalloc(0)
戻るようなものを可能にすることを信じていますNULL
。
delete []
割り当てから取得したポインタも必要です。
奇妙なことに、C ++では、ゼロバイトが要求された場合でも、オペレーターnewが正当なポインターを返す必要があります。(この奇妙なサウンドの動作が必要なため、言語の他の場所での処理が簡単になります。)
「アイテム51:新規作成および削除の際は慣例に従う」で、Effective C ++ Third Editionがこのように言っているのを発見しました。
私がテストしたので、新しいint [0]が余分なスペースを消費することを保証します。
たとえば、次のメモリ使用量
int **arr = new int*[1000000000];
より大幅に小さい
int **arr = new int*[1000000000];
for(int i =0; i < 1000000000; i++) {
arr[i]=new int[0];
}
2番目のコードスニペットのメモリ使用量から最初のコードスニペットのメモリ使用量を引いたものが、多数の新しいint [0]に使用されるメモリです。