12

bad_allocにいくつかの負の引数を渡して、例外をテストしようとしましたnew[]。小さな負の数を渡すと、期待どおりの結果が得られます- a bad_alloc。ただし、 を渡す-1と、オブジェクトが何千回も構築され (コンストラクターで静的カウンターを出力します)、アプリケーションが segfault で終了することがわかります。

new[]は符号付き整数をにsize_t変換します。-1size_t-2maximum - 1

new[]では、巨大な数を受け取ったときに例外をスローするのに、最大数を受け取ったときに割り当てようとするのはなぜsize_tですか? 1111...11111...0forはどう違いnew[]ますか?:)

前もって感謝します!

4

1 に答える 1

18

ここに私の野生の推測があります:

多くの実装では、アロケータは割り当てられた領域の隣にいくつかのメタデータを配置します。
(たとえば、割り当てのサイズ。) したがって、実際には、要求した以上の割り当てを行っていることになります。

size_t32ビットだとしましょう。32 ビット用にコンパイルされています。


あなたがするとき:

int *array = new int[-1];

は(オーバーフロー後) に-1なります。-1 * 4 bytes = 4294967292ただし、アロケーターの実装が、割り当てられた領域の隣に 4 バイトのメタデータを配置する場合。実際のサイズは次のようになります。

4294967292 + 4 bytes = 0 bytes (after overflow)

したがって0、実際にはバイトが割り当てられます。

メモリにアクセスしようとすると、すぐに範囲外になるため、segfault が発生します。


では、次のようにします。

int *array = new int[-2];

は(オーバーフロー後) に-2なります。-2 * 4 bytes = 42949672884 バイトのメタデータを追加すると、4294967288 + 4 = 4294967292.

アロケータが4294967292OS からバイトを要求すると、拒否されます。だからそれはスローしbad_allocます。


したがって、基本的には、アロケーターがメタデータを追加した後にオーバーフローするかどうかに違いが生じる可能性が-1あります。-2

于 2012-03-13T09:21:50.713 に答える