メモリ不足でコンストラクタが呼ばれない

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のこの仕様はやっぱりおかしいと思うな。