3.2 大きく確保して、その一部を使う戦略

サイズが事前に分かっていなくても、それがそんなに大きくなければ
#define MAXM (10)
#define MAXN (10)

int main(void)
{
   double b[MAXM][MAXN]; // これは 800 バイトのメモリを占める (と分かる?)
   int m, n, i, j;
   printf("m,n="); scanf("%d%d", &m, &n);
   if (m > MAXM || n > MAXN) { // 一応エラー・チェック
     ...
   }
   for (i = 0; i < m; i++)
     for (j = 0; j < n; j++)
        ...
のようにすることが考えられる。 つまり、記憶領域を大きめに確保して、その一部だけを使う、ということである。

でもあまりお勧めできない。 ベクトルならば大したことにはならないだろうけれど、 行列の場合はサイズの制限は案外きつい。 自分が現在使っている C 言語処理系で、 スタック領域のデフォールトのサイズがいくらであるか、 即答できる人は多くないだろう (僕は覚えていません -- 今使っている Mac で調べたら 8MB だった)。

サイズが事前にわからない、ある程度以上大きい、という場合、 次のようにする方がよい。

#define MAXM (200)
#define MAXN (200)
double a[MAXM][MAXN]; // 静的に大きめに確保

int main(void)
{
   int m, n, i, j;
   printf("m,n="); scanf("%d%d", &m, &n);
   ...

上と変わらないように感じるかもしれないが、 a を関数の外で定義する (静的変数として定義する) ことが重要なポイントである。 これならばスタック領域のサイズは気にならない。


このやり方はまあまあ使える。 しかし関数に引数として渡すときに少し悩ましいことが起こる。 これは案外、説明に手間取るので、項を改める。

桂田 祐史
2017-03-06