variable length array で配列の要素数の限界を調べた(しかしvariable length arrayあまり関係ない)
Sun Apr 21 19:51:29 JST 2013 (modified: Fri Sep 29 21:38:45 JST 2017)
views: 3532, 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;"%d\\n",nums[i]);
printf(
}
}
int main(int argc, char const* argv[])
{int num = atoi(argv[1]);
"%ld\\n",num*sizeof(int));
printf(
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万レベルでガボッと配列を確保していいようです。これならいいか。
でも、自分で配列の個数の上限をチェックするコードを書く事になるんだから、決まった数の配列を作って、それを使った方がいいんじゃないのかなあ???
うーん。
続く。