5

2.9GBのchar配列を割り当てたい

  database = (char*) malloc((2900 * 1000000 * sizeof(char)));

これにより、整数オーバーフローの警告が表示され、がmalloc返されますNULLmallocパラメータはタイプであり、 size_tドキュメントによるとタイプはです unsigned int

したがって、最大値はUINT_MAX少なくとも2.9GBである必要があります。MAX_INTしかし、私がmalloc失敗より多くを割り当てようとすると。size_tこれは、私のシステムでint型であることを意味 しますか?これを確認するにはどうすればよいですか?見た

/usr/include/stdlib.h 

./lib/gcc/x86_64-redhat-linux/4.1.1/include/stddef.h 

しかし、の定義が見つかりませんsize_t。どうもありがとう

4

3 に答える 3

10

パラメータはタイプsize_tであり、タイプmallocの可能な値を受け入れるために必要ですsize_t。「受け入れる」とは、それほど多くを割り当てる必要があるという意味ではないことに注意してください。つまりmalloc、オーバーフローの問題が原因で、与えた非常に大きな数を小さい/負の数と誤解して、小さすぎるバッファを返し、プログラムが防御できない重大な検出できない脆弱性を作成することは許可されません。malloc非常に大きなオブジェクトの割り当てに失敗する可能性がある理由はたくさんあります。

  • その量のメモリはシステムから利用できません
  • 断片化のため、大きな仮想アドレスの連続した範囲は利用できません
  • 任意の制限

この場合、私はそれらをそれほど恣意的とは見なしませんが、3番目の恣意的な制限が表示されているのではないかと思います。より大きな割り当て(およびオブジェクトの存在)を禁止する非常に正当な理由がありますSIZE_MAX/2:そのような大きなオブジェクト内のポインター間の差を取ると、結果が(符号付き)に収まらない場合に(非常に危険な)整数オーバーフローと未定義動作が発生します)タイプptrdiff_t。したがって、堅牢な32ビットシステムでは、仮想アドレス空間のサイズは4GBですが、単一のオブジェクトの最大サイズは2GBになります。

于 2012-03-02T17:56:16.060 に答える
9

ここには2つの問題があります。

まず、オーバーフロー警告:とは両方とも2900タイプ1000000intあるため、それらを乗算した結果もタイプintです。結果は32ビットの符号付き整数で表すことができないため、オーバーフローします。size_t符号なし演算を使用するには、1つ(または両方)の引数をキャストする必要があります。

(または、sizeof(char)タイプがであるため、を最初の2つの用語のいずれかに移動することもできますが、常にでsize_tあるため、削除することもできます。)sizeof(char)1

malloc次に、割り当てることができる最大サイズは、実行しているプラ​​ットフォームとプログラムの現在の状態の両方によって異なります。要求を満たすのに十分な連続アドレス空間が残っていない場合、明らかにmalloc失敗します。

さらに、実行しているプラ​​ットフォームには、動的に割り当てることができるオブジェクトの大きさに上限がある場合があります。その上限を確認するには、プラットフォームのドキュメントを参照する必要があります。

size_tは常に署名されており、常に署名されていないintため、確かにそうではありません。intsize_t

于 2012-03-02T17:52:40.393 に答える
1

mallocが割り当てることができる最大サイズは、実行しているプラ​​ットフォームとプログラムの現在の状態の両方によって異なります。要求を満たすのに十分な連続アドレス空間が残っていない場合、mallocは明らかに失敗します。

于 2017-09-28T10:51:36.327 に答える