2012-03-02 3 views
3

を越えて行くことができない私はCでsize_t型のmallocパラメータの制限はありますか?ドキュメントは、それがUINT_MAXの上限を持っていると言うが、私はINT_MAX

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

で2.9ギガバイトのchar型の配列を割り当てたいこれは、整数オーバーフローの警告とmalloc戻りNULLを与えます。 mallocのパラメータは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の定義を見つけることができません。ありがとうございました

+0

これは、十分なRAMがないことを意味します。 –

+0

コンピュータに12GBのRAMがあります。 – Ross

+6

また、システムが32ビットであることに言及するのを忘れてしまった。 –

答えて

9

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

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

(あるいは、それは常に1あるので、あなたにもちょうどsizeof(char)を削除することができますが、あなたが、その種類はsize_tているので、最初の2項の一つであることがsizeof(char)を移動することができます。)

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

さらに、実行しているプラ​​ットフォームには、動的に割り当てることができるオブジェクトの量の上限がある場合があります。その上限が何であるかは、プラットフォームのドキュメントを調べる必要があります。 intは常に署名とsize_tは常に符号なしですので

size_tは、確かにintではありません。

+0

ありがとうございます。私はまだsize_tがどこに定義されているのだろうかと思っています。私は私の投稿に名前を付けた2つのファイルのうちの1つにあるべきではありませんか? – Ross

+1

はい、それは ''、または ''に含まれるいくつかのヘッダで定義されるべきです。 –

+1

'strtoul'を使う方が良いでしょう。' strtoul'は 'unsigned long'を返し、実際にはエラーチェックが可能です。 'atoi'の失敗は、値ゼロの成功した解析と区別できません。 –

10

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

  • 多くのメモリが原因の断片化に
  • システムから利用できないことを、大は任意
  • 利用可能であることを、仮想アドレスのない連続した範囲は、制限

この場合、3番目の恣意的な制限が表示されている可能性があります。割り当てが許されない理由は、SIZE_MAX/2より大きくなります。そのような大きなオブジェクト内のポインタの違いを取ると、結果が((非常に危険な)整数オーバフローおよび未定義の動作になります署名付き)タイプptrdiff_t。したがって、堅牢な32ビットシステムでは、仮想アドレス空間のサイズは4GBですが、1つのオブジェクトの最大サイズは2GBになります。

+3

'ptrdiff_t'の署名の良い点。 – ninjalj

1

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

関連する問題