Re: mysterious memory corruption, very confused
- From: Nobuyoshi Nakada <nobu@xxxxxxxxxxxxx>
- Date: Sun, 6 Jul 2008 20:15:44 -0500
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.
--
Nobu Nakada
.
- Follow-Ups:
- Re: mysterious memory corruption, very confused
- From: Tim Pease
- Re: mysterious memory corruption, very confused
- Prev by Date: Re: #pragma and index_info() was ([ANN] amalgalite 0.2.1 Released)
- Next by Date: Re: creating dynamic hashmap
- Previous by thread: Re: mysterious memory corruption, very confused
- Next by thread: Re: mysterious memory corruption, very confused
- Index(es):
Relevant Pages
|