質問者の いしもと です。

和田さん、中田さん、アドバイスありがとうございます。
知らないことばかりで、とても勉強になります。
ただ、お二方のアドバイスを実行しましたが、悲しいこと
に望むような結果は得られませんでした。
以下、現状報告です。
【和田さん案】
かなり長い配列を引数に指定してもseg faultしなくなった。
しかし、returnされた配列をruby program内で扱おうとす
るとseg faultが発生する。(引数配列の長さによっては発生
しないこともあるが、returnされる配列が少しおかしい。)
(例1)
ary.length==3,000,000
result=calc6(ary, etc)
p result[0] => seg fault
(例2)
ary.length==1,000,000
result=calc6(ary, etc)
p result[0] => value             # ?
p result[-1] => [index, value] # ok

【中田さん案】
seg faultはしなくなった。しかし、returnされる配列が
空になっている。
(例)
result=calc6(ary, etc)
p result.length => 0

現在、和田さんが紹介して下さった青木さんのサイトや
rhgなどを見ながら(にわか)猛勉強中です。volatileあた
りも気になっていますが、それ以前に基礎を固める必要も
痛感しています...
引き続きアドバイスなど頂けましたら幸いです。
___________________
いしもと まさと(石本 将人)

 
2007年04月08日 16:23 の "Nobuyoshi Nakada" <nobu / ruby-lang.org>のメール:
>なかだです。
>
>At Sun, 08 Apr 2007 13:35:28 +0900 (JST),
>ysk wrote in [ruby-ext:02319]:
>> VALUE型をヒープに確保した場合は
>> rb_gc_markという関数でそのことをRuby側に
>> 伝えてやる必要があるようです。
>
>rb_gc_mark()をmark用関数以外から呼んではいけません。
>
>この場合はresultを先に確保しておいて、そのptrを使うということで
>いいのではないでしょうか。
>
>static VALUE
>si_calc6(self, ary1d, x0, y0, a)
>    VALUE self;
>    VALUE ary1d;
>    VALUE x0;
>    VALUE y0;
>    VALUE a;
>{
>    unsigned int i;
>    /* 引数をc言語の型に変換 */
>    int x0c = NUM2INT(x0);
>    int y0c = NUM2INT(y0);
>    double ac = NUM2DBL(a);
>    long length = RARRAY(ary1d)->len;
>    VALUE result = rb_ary_new2(length);
>    VALUE *items = RARRAY_PTR(result);
>    VALUE klass = RBASIC(result)->klass;
>
>    VALUE item;
>    VALUE t;
>    VALUE xt;
>    double y;
>
>    RBASIC(result)->klass = 0;
>    for (i = 0; i < length; i++){
>        t = INT2FIX(i + x0c);
>        y = NUM2DBL(rb_ary_entry(ary1d, i));
>        xt = rb_float_new(y0c - (y * ac));
>        item = rb_ary_new3(2, t, xt);
>        items[i] = item;
>    }
>    RBASIC(result)->klass = klass;
>
>    return result;
>}
>
>-- 
>--- 僕の前にBugはない。
>--- 僕の後ろにBugはできる。
>    中田 伸悦
>
>