variable length array で配列の要素数の限界を調べた(しかしvariable length arrayあまり関係ない)

Sun Apr 21 19:51:29 JST 2013 (modified: Fri Sep 29 21:38:45 JST 2017)
views: 3298, keywords:プログラミング,C言語,ulimit,variable この記事は最終更新日が7年以上前のものです。

前回の variable length array、なんでそんなに自分が気持ち悪いと感じるのかと考えてみました。結果、WindowsでVisual C++を昔(4.0~6.0あたり)使っていたときに、デフォルトのスタック領域の大きさがそんなに大きくなく、

int aho[100000];

などとすると実行時エラーが起こっていたのが遠因のようです。スタック領域はビビりながら使う物で、variable length array などとんでもないと。

例えば、このページに Windows CEのケースが書いてあります。確か Windows 95, 97 で Visual C++ を使っても全く同じだったと記憶しています。

しかし、もう15年以上も経っているしOSも違うので、自分の感覚は調整しないといけません。実験しましょう。なぜこのクソ忙しいのにそんなことをするのか。それは、今出ている会合がもう休み無しでもうすぐ4時間経過しようとしているからです。息抜きしないと死ぬぞこれ。

まず、自分のマシーンのスタックの大きさを調べます。ulimitというコマンドで調査できます。

uedamac:~ ueda$ ulimit -s
   8192
   //単位をバイトに直す。
   uedamac:~ ueda$ ulimit -s | awk '{print $1*1024}'
   8388608

ということで、int型だとだいたい 2百万くらいが配列の要素数の限界と言えそうです。

次に取り出しますのは前回の気持ち悪いコードをちょっと修正したもの。

uedamac:~ ueda$ cat hoge.c
   #include <stdio.h>
   
   void kidding_me(size_t size)
   {
       int nums[size];//気持ち悪い
   
       int i;
       for(i=0;i<size;i++){
           nums[i] = i;
           printf("%d\\n",nums[i]);
       }
   }
   
   int main(int argc, char const* argv[])
   {
    int num = atoi(argv[1]);
    printf("%ld\\n",num*sizeof(int));
    kidding_me(num);
   
    return 0;
   }

オプションで配列の個数を指定すると、それだけスタックを確保してくれます気持ち悪いですねー。

コンパイルして、とりあえず200万を指定して実行してみます。

uedamac:~ ueda$ gcc ./hoge.c
   uedamac:~ ueda$ ./a.out 2000000 | tail -n 1
   1999999

甲斐甲斐しく動いています。

じゃあ動かなくなるのはどれくらいなんだ、と。

いろいろ調べた結果、209万6105でSegmentation faultが発生しました。素直な結果でよかったよかった。

uedamac:~ ueda$ ./a.out 2096104 | head
   8384416
   0
   1
   2
   3
   4
   5
   6
   7
   8
   uedamac:~ ueda$ ./a.out 2096105
   8384420
   Segmentation fault: 11

ということで、私のMacだと100万レベルでガボッと配列を確保していいようです。これならいいか。

でも、自分で配列の個数の上限をチェックするコードを書く事になるんだから、決まった数の配列を作って、それを使った方がいいんじゃないのかなあ???

うーん。

続く。

ノート   このエントリーをはてなブックマークに追加 
 

prev:C言語(C99)の variable length array というものを初体験 next:RoboCup JapanOpen 2013の手伝いをしています

やり散らかし一覧

記事いろいろ