わたなべです。

できればちゃんと実行できる拡張ライブラリにして欲しかったんですが…。
試せなかったんで、気になったことを書きます。

ABE Shigeru <shiger-a / nifty.com> writes:

: ruby.h で定義されている ALLOC_N に数 MB 単位でメモリを要求すると、周辺
:のメモリが破壊されてしまうようです。わかりにくいかもしれませんが、テスト
:に使ったコードを書いておきます。

GC_MALLOC_LIMITが8MBだから、もし
    t->b = ALLOC_N( int, 1024 * 1024 );
だと起きないとすれば、GC_MALLOC_LIMITより多く要求したときに、
rb_gcされてしまい、その結果

:static void test_free ( struct tagTest * t )
:{
:    ruby_xfree( t->a );
:    ruby_xfree( t->b );
:    ruby_xfree( t->c );
:    ruby_xfree( t );
:}

ここで、tがfreeされて、たまたま先頭のmemberであるaにfree
listの情報が書き込まれているんだと思われます。
この
    ruby_xfree( t );
前後でt->aの値を調べてみるといいかもしれません。

:static VALUE test ( VALUE klass )
:{
:    struct tagTest *t;
:    VALUE  v;
:    
:    v = Data_Make_Struct( rb_cData, struct tagTest, NULL, test_free, t );
:    t->a = t->c = NULL;
:    t->b = ALLOC_N( int, 1024 * 1024 * 5 );
:    fprintf( stderr, "a=%p,b=%p,c=%p\n", t->a, t->b, t->c );
:    
:    return Qnil;
:}

vが宙に浮いてます。
    VALUE volatile v;
でどうでしょう?

あ、ひょっとしてこれを追加するぐらいで試せたのか。
void Init_tagTest()
{
    test(0);
    test2(0);
}

-- 
わたなべひろふみ