- ベストアンサー
行列積の問題で
行列積の問題で1000×1000の問題を解きたいと思っています。 100×100ならできるのですが、1000×1000にするとセグメンテーションエラーになってしまいます。 一部引用すると・・・ #define N 1000 size=N unsigned long int a[N][N],b[N][N]; unsigned long int c[N][N]; for(i=0; i<size; i++){ for(j=0; j<size; j++){ c[i][j] = 0; for(k=0; k<size; k++){ c[i][j] = c[i][j] + a[i][k]*b[k][j]; } こんな感じです。 初歩的な質問だと思いますがお願いします
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
Cの標準的なメモリーモデルであったかどうかは自信ありませんが、 一般的に二つのメモリー領域が区別されます。 一つはプログラムの進行に伴って自動的に増減する領域、 もう一つは常に存在する、またはプログラム自体の要求に応じて 増減する領域です。前者をスタック、後者をヒープと言います。 関数内部の変数は一般的にスタックに、外部の変数はヒープに 置かれます。スタックの特徴は、領域を増減する際の基準となる アドレスがあって、そこからの相対的な位置の指定で操作するように なっていることです。この相対的なアドレッシングの幅に制限が ある場合があり、そのため内部変数はあまり大きな領域を取れない のです。 乱暴なくらい大雑把な説明ですが、お分かり頂けるでしょうか。
その他の回答 (2)
- furyfox
- ベストアンサー率56% (58/103)
処理系によりますが 連続する64キロ以上の静的メモリは確保できないのです。 そういう場合ポインタをつかって動的確保をおこないます。 #define N 10000 #include <stdio.h> #include <malloc.h> int main(){ int i; unsigned long **a; a = (unsigned long **)malloc(sizeof(unsigned long *) * N); for(i=0;i<N;i++){ *(a + i) = (unsigned long *)malloc(sizeof(unsigned long) * N); } a[9999][9999] = 999; printf("%d\n",a[9999][9999]); printf("%d\n",*(*(a+9999)+9999)); for(i=0;i<N;i++){ free(*(a + i)); } free(a); return 0; } >なぜグローバル変数にすれば実行ができるのでしょうか? 自身はありませんがグローバル変数は断片的に確保されているのでしょう。
お礼
ありがとうございます。 ポインタを使ってメモリを確保すれば可能なのですね。 プログラムを書き直して見ます。 ありがとございました
- ranx
- ベストアンサー率24% (357/1463)
第1の可能性として、コンパイラやシステムの条件によって、 自動変数の領域にとれるメモリーのサイズが限られている場合が あります。この場合、例えば void func1() { int a[N]; ・・・ } となっているものを int a[N]; void func1() { ・・・ } のように、関数の外に出すとうまくいく場合があります。 第2の可能性として、そもそもメモリーが足りないのかも しれません。質問のプログラムは、Nを1000とすると、 三つの変数だけで12Mbyteものメモリーを必要とします。 他の変数やプログラムと合わせて、メモリーが確保できない ようでしたら、根本的にアルゴリズムを変えるしかないと 思います。
お礼
ありがとうございます。 回答のとおり、質問してすぐに、グローバル変数にすればできることに気づいたのですが・・・なぜグローバル変数にすれば実行ができるのでしょうか? よろしければ、補足お願いします
お礼
わかりやすい説明ありがとうございます。 こういう問題は参考書などになかなか載っていないので非常に困ります^^;;; またお願いいたします