2011-12-09 28 views
2

DNA配列の分析を行うプログラムを書いています。 このこと以外はすべて正常に動作します。 サイズm * nの2次元配列を宣言します。ここでmとnは入力ファイルから読み込まれます。 問題は、mとnがあまりにも大きくなる場合です。例として、m = 200とn = 50000の場合 次に、配列を宣言する行にsegフォルトが発生します。大きな2D配列の場合のSegフォールト

array[m][n]; 

どのようにこれを克服するためのアイデア。私はロジック全体がこの配列をどのように処理するかに依存するので、このような配列が必要です。

+0

あなたは300メガバイト(32ビットタイプを仮定します)を要求しています...それを新しいもので動的に割り当ててみてください。こんにちは、ありがとうございます。 –

答えて

4

スタックスペースが不足している可能性があります。
mallocを使用して、ヒープに配列を動的に割り当てることはできませんか?

あなたがそれを行う方法がわからない場合はthisの答えを見てしたいことがあります。

+0

ヒントを得ました.. –

+0

+1は正解ですが、リンクは良くありません。反復されたポインタの配列に行く必要はありません。 'double(* array)[n] = malloc(double [m] [n]);'だけです。 –

0

スタック領域が不足している可能性があります。

たとえば、Windowsは各スレッドに1MBのスタックを与えます。配列に整数が含まれていて、それをスタック上に作成しようとすると、40MBのスタック変数が作成されます。

代わりに動的にヒープに割り当てる必要があります。

1

あなたが使用しているタイプはわかりませんが、次のコードではintと仮定しています。

よりもむしろこれをやって:

int array[200][50000]; 

はこれをやってみてください。

int** array = (int**)malloc(200); 
for (int i = 0; i < 200; i++) 
{ 
    array[i] = (int*)malloc(50000); 
} 

この "ヒープ" メモリではなく、 "スタック" のメモリを割り当てます。あなたは300メガバイト(32ビットタイプを使用している場合)以上を求めているので、多分 "スタック"メモリがないでしょう。

for (int i = 0; i < 200; i++) 
{ 
    free(array[i]); 
} 
free(array); 

は、mとnの代わりに、私は上記の使用する定数の自由に利用して構い:あなたが持つ配列で終わった後

は、クリーンアップに確認してください!

編集:これはもともとC++で書いてあり、C言語に変換されました。私はCメモリの割り当て/割り当て解除でやや錆びていますが、正しいと思います。

+0

Ahhh、cではないC++。編集する分を教えてください。 –

+0

ありがとうございます。 同じ方法で配列を逆参照できますか? 配列[100] [500]にアクセスしたい場合は、通常の2D配列のように配列[100] [500]を使用できますか? –

+0

はい。 int [] []は密かにint **です。 :) –

0

アレイ(ローカルの場合)がスタックに割り当てられます。プロセス/スレッドのスタックサイズには一定の制限があります。スタックが肥大していると、問題が発生します。

しかし、mallocを使ってヒープに配列を割り当てることができます。典型的なヒープ・サイズは4GBです(これはOS /アーキテクチャーによって多少なりともなります)。 mallocの戻り値を調べて、配列のメモリーが正しく割り当てられていることを確認してください。

1

他にも、大きなVLA(可変長配列)をスタックに割り当てることはお勧めできません。mallocとそれを割り当てます。

double (*array)[n] = malloc(sizeof(double[m][n])); 

、あなたが以前のようにオブジェクトを持っている、それはコンパイラが完全に個々の要素に対処する方法を知っているということですarray[i][j]と割り当てはまだメモリ内にあなたに1つの連続したブロブを提供します。

はちょうどあなたのスコープの終わりに

free(array); 

を行うことを忘れないでください。

+0

C /メモリについてもっと知っていると思いますので、私が間違っている箇所に修正してください。彼の値mとn(200,50000)で、私の答えは200の別々の1.5MBのチャンクを要求しているのに対し、あなたの答えは300MBの連続したメモリチャンクを要求しています。メモリ断片化のために小さなチャンクを得る可能性はあまり高くありませんか? –

+0

あなたの質問を正しく理解しているかどうかわかりません。最近のシステムでは、このような大きなチャンクは「匿名マッピング」によって割り当てられます。つまり、システムは仮想メモリ内のアドレス範囲を予約し、必要に応じて物理ページを割り当てます。その割り当てのすべてのエフェクトの割り当てを解除すると、その割り当ては消えます。あなたの方法のために、システムは個々のチャンクを後で再利用することがあります。それを繰り返すと、おそらく断片化が増えるでしょう。あなたは、 'malloc'システムに、同時にすべてが同時に解放されるような多くの割り当てを行うことによって不必要にストレスを感じます。 –

関連する問題