Tim Pease
7/7/2008 4:36:00 PM
On Jul 6, 2008, at 7:15 PM, Nobuyoshi Nakada wrote:
> Hi,
>
> At Mon, 30 Jun 2008 15:47:19 +0900,
> Seebs wrote in [ruby-talk:306636]:
>> It is. There's a loop of
>> VALUE x;
>> char **foo = malloc(buncha char *);
>>
>> for (big list of things) {
>> x = rb_obj_as_string(y);
>> foo[i] = GetStringValue(x);
>> }
>
> It's your bug.
>
>> The idiom of using rb_obj_as_string, and then using the value, is
>> common in
>> the Ruby source. It works. ... It works *as long as you don't
>> allocate
>> anything more before you're done with it*. What ends up happening
>> is that,
>> if enough of the objects in question need a new string allocated by
>> rb_obj_as_string, sooner or later you end up invoking the garbage
>> collector.
>> Now, since there's only one x, the garbage collector assumes the
>> current
>> rb_obj_as_string() return is in use, *and the others aren't*. So
>> it might,
>> if it wants the space, free one... And then the memory gets reused.
>
> Because you drop the references to the created objects. You
> have to keep the objects but not only the pointers.
>
>> I submitted a more detailed bug report to the ruby-pg project, and
>> I've
>> adopted a workaround (possibly very inefficient) involving an array
>> of VALUE
>> objects and rb_gc_{un}register_address. It's ugly but it
>> eliminates the bug.
>
> VALUE x, array;
> char **foo = malloc(buncha char *);
>
> for (big list of things) {
> x = rb_obj_as_string(y);
> rb_ary_push(array, x);
> foo[i] = GetStringValue(x);
> }
>
> By keeping the values in an automatic variable `array', they
> are marked and won't be freed.
>
I am wondering why the strings (returned from rb_obj_as_string) will
be garbage collected but the array will not be garbage collected? Both
have the same local scope, and they are not referenced by any other
ruby object.
Please explain when you have time.
Blessings,
TwP