From: Charles Mills Date: 2005-05-17T08:15:30+09:00 Subject: Re: rb_gc_mark question Ara.T.Howard wrote: > i reading some code attm that goes: > > static VALUE convertgslmatrixToRubyMatrix(gsl_matrix *dm) > { > int i, j; > volatile VALUE result; > assert(dm); > // printf("Trying to convert dm %p\n", dm); > // printf("With size %d, %d\n", dm->size1, dm->size2); > volatile VALUE rows = rb_ary_new(); > rb_gc_mark(rows); > for (i = 0; i < dm->size1; i += 1) { > volatile VALUE currow = rb_ary_new(); > rb_gc_mark(currow); > rb_ary_push(rows, currow); > for (j = 0; j < dm->size2; j += 1) { > double val = gsl_matrix_get(dm, i, j); > VALUE rval = rb_float_new(val); > rb_gc_mark(rval); > rb_ary_push(currow, rval); > } > } > result = rb_funcall(cMatrix, rb_intern("rows"), 2, rows, Qnil); > rb_gc_mark(result); > return result; > } > > > now, everything i know says this should be something along the lines of: > > static VALUE > convertgslmatrixToRubyMatrix (gsl_matrix * dm) > { > int i, j; > VALUE result; > VALUE rows = rb_ary_new (); > for (i = 0; i < dm->size1; i += 1) > { > VALUE currow = rb_ary_new (); > rb_gc_mark (currow); > rb_ary_push (rows, currow); > for (j = 0; j < dm->size2; j += 1) > { > double val = gsl_matrix_get (dm, i, j); > VALUE rval = rb_float_new (val); > rb_ary_push (currow, rval); > } > } > result = rb_funcall (cMatrix, rb_intern ("rows"), 2, rows, Qnil); > return result; > } > > (please correct me if i'm wrong) > > or nasty things will happen in memory right? what would it do to call > rb_gc_mark on ruby objects like this? > You shoud just not call rb_gc_mark at all. Not sure if it even matters, but it is possible that objects you mark using rb_gc_mark outside of a mark and sweep cycle will hang around AFTER some of there fields have been GCed - like an array whose elements have been GCed, but is still -alive-. This will only happen if the stack does not overflow when marking and the only way this could be a problem is by using the object space API. Anyway, hopefully whoever wrote this code hopefully wasn't modivated by my overly paranoid/incorrect past posts about the Ruby GC. Also you could use rb_ary_new2 to save ruby from having to resize the array since you know the size ahead of time. -Charlie