2011-10-06 15 views
2

私は本当にCの新機能ですので、これは絶対初心者の質問ですが、申し訳ありませんが、私は大規模な配列を構築しているときにセグメント化エラーが発生しています:大きな配列はCでセグメンテーションエラーを返します

unsigned long long ust_limit; 
unsigned long long arr_size; 

/* ust_limit gets value around here ... */ 

arr_size = ((ust_limit + 1)/2) - 1; 
unsigned long long numbs[(int)arr_size]; 

これはust_limitの一部の値で機能しますが、約4.000.000を超えるとセグメント化エラーが発生します。私が望むのは、可能なセグメンテーションを検出し、正常に失敗することです。セグメンテーション違反の原因となる値を知るにはどうすればよいですか。そして、これはプラットフォームに依存しているのでしょうか?

答えて

5

あなたがスタック上に非常に大きな配列を作成しているので、あなたが最も可能性が高い、スタックオーバーフローを取得しています。これを避けるために、動的にメモリを割り当てる:

unsigned long long *numbs = malloc(arr_size * sizeof(unsigned long long)); 

その後、あなたが配列で終了したら、再びそれを解放:

free(numbs); 
+0

このようにしてアレイを使用するような麻痺を使用することはできますか?たとえば、インデックスにアクセスできますか? – yasar

+0

はい、同じ方法で使用できます。例えば、インデックス作成は配列上で動作するので、いくつかのメモリへのポインタに対して同じ動作をします。 – sth

1

サイズに制限があるスタックフレーム上の配列ストアは、代わりにmallocを使用します。

unsigned long long *numbs = malloc(arr_size * sizeof(long long)); 
// don't forget to free after use 
free(numbs) 
+0

を、私はそれを行う方法についてわからない、私は本当に初心者ですこれでは、一例でしょうか? – yasar

1

スタックが多すぎます。制限はプラットフォームによって異なります。

正確な制限は、OSによって異なります。これらの制限は、一部のオペレーティングシステムではある程度変更することができます。

大量のメモリの場合は、mallocおよび/またはcalloc(およびfree)のヘッドを使用する必要があります。

1

numbsは可変長配列(VLA)です。

VLAはブロックスコープ(つまり、関数内)でのみ作成できます。それらは他のローカル変数と同様に、通常スタックに割り当てられます。

残念ながら、この言語は、ローカル変数の割り当て失敗を検出または処理する方法を提供していません。あまりにも多くのメモリを割り当てると、あなたが幸運ならば、のプログラムは、にクラッシュします。

コンパイル時にサイズが不明なラージオブジェクトは、malloc()で割り当てられます(つまり、割り当てを追跡し、free()で解放する必要があります)。

arr_sizeからintにキャストする必要はありません。 ust_limitarr_sizeの両方がsize_t<stddef.h>で定義されている)である必要があります。

例:

unsigned long long numbs = malloc(arr_size * sizeof *numbs); 
/* And later, when you're done with it */ 
free(numbs); 
関連する問題