From: William Djaja Tjokroaminata Date: 2002-10-22T23:57:05+09:00 Subject: Re: rb_gc_register_address problem Hi Paul, Paul Brannan wrote: > I'm storing command-line arguments for later use, to pass to a function > that expects an array of char*. In this case then what you want is probably something like std::vector foo; void func(int argc, VALUE * argv, VALUE self) { int length; char *str; rb_str2cstr (argv[0], &length); str = malloc (sizeof(char) * (length + 1)); strcpy (str, STR2CSTR(argv[0])); foo.push_back(str); } Of course, I have created a macro/function that performs a task as above so that I can simply write std::vector foo; void func(int argc, VALUE * argv, VALUE self) { foo.push_back(create_str_from_rubystr (argv[0])); } My philosophy in Ruby-C integration: separate the C-part and the Ruby-part as much and as far as possible; we are better-off in the long run this way. (deleted) > But if the GC stores a VALUE* instead of a VALUE, this is an extra (and > seemingly unnecessary) indirection. I was curious if there was a reason > for it, other than to prevent me from doing what I did. I think this is because all Ruby VALUE's of type pointer (not immediate object) is allocated from a single heap. As you call rb_global_variable(), Matz created a linked list containing all the addresses of the global variables. During the gc marking process, Matz simply goes through this list and marks the VALUE pointed by each VALUE*. If you had given Matz a VALUE instead, during the gc marking process Matz has to go through the heap to find the exact VALUE and mark it for each global variable, and now the process is of O(N**2) instead of O(N). Regards, Bill