メモリ不足でコンストラクタが呼ばれない
AIXで、datasizeが不足するとコンストラクタが呼ばれないという現象にあってハマったので、覚書。
こんなコードを書いた。
const int SIZE = 50000000; class Class{ int buf[SIZE]; public: Class(void){ printf("Hello\n"); }; }; int main(void) { printf("Buffer size = %d\n",sizeof(int)*SIZE); printf("Class size = %d\n",sizeof(Class)); Class *obj = new Class(); delete obj; }
このクラスの配列bufは、Classがnewされたときに
ヒープに取られると思ってた。事実、手元のCentOSでは、
実行結果はこうなる。
%limit datasize 1m %limit stacksize 1m %limit cputime unlimited filesize unlimited datasize 1MB stacksize 1MB coredumpsize 0kB % ./a.out Buffer size = 200000000 Class size = 200000000 Hello
クラスのサイズは200Mだが、datasizeとstacksizeを1Mに制限しても走る。
しかし、AIXで、さらにコンパイラがxlc++だとこうなる。
% limit datasize 190m % ./a.out Buffer size = 200000000 Class size = 200000000 % limit datasize 210m % ./a.out Buffer size = 200000000 Class size = 200000000 Hello
つまりdatasizeが足りないと、クラスのインスタンスが作れない。
もちろん、bufをポインタにして、クラス内部でnewすれば
class Class{ //int buf[SIZE]; int *buf; public: Class(void){ buf = new int[SIZE]; printf("Hello\n"); delete [] buf; }; };
% limit datasize 1m % ./a.out Buffer size = 200000000 Class size = 4 Hello
とコンストラクタは呼ばれる。ちなみにAIXでもg++だとbad::allocを出してくれるが、xlc++だとコンストラクタが呼ばれないままスルーされてしまう。
メモリの取り方はOSの自由だと思うけれど、AIXのこの仕様はやっぱりおかしいと思うな。