From: "Iñaki Baz Castillo" Date: 2012-05-31T05:51:19+09:00 Subject: [C exten] The last question about rb_gc_register_address(): a case in which in works with dynamic memory Hi, what I understand (after some useful threads in this mailist) about rb_gc_register_address() is that it's only valid for fixed memory (in the stack). So if for example I have a global/static VALUE in my MyLibrary_init() function, I should use it to avoid GC (it's not referenced by any other Ruby object in Ruby land): ------------------------------------------- static VALUE string_Via; void MyLibrary_init(void) { some_string = rb_str_new2("HELLO WORLS"); // If I don't do this, it will be GC'd: rb_gc_register_address(&some_string); } ----------------------------------------- But I cannot use rb_global_variable(), for example, to avoid GC for a VALUE object passed as function parameter since I'm trying to register its *memory address*, which would get invalidated after the function and when the variable gets out of the Ruby scope. Ok, it makes sense. But I've found a way to make it to work and would like to share it (to know if it's a risk or it just works in certain cases): ----------------------------------------- struct data_struct { VALUE data; int lalala; long lololo; } VALUE MyLibrary_some_method(VALUE self, VALUE data) { struct data_struct* my_data_struct = ALLOC(struct data_struct); my_data_struct->data = data; // This WONT avoid GC: // rb_gc_register_address(&data); // But this WILL avoid GC: rb_gc_register_address(&(my_data_struct->data)); } --------------------------------------- The memory address for which I'm calling rb_register_address() is allocated by me, and I will not free it for now. And before freeing it I will call rb_gc_unregister_address(&(my_data_struct->data)), so it "should" be safe. So, could somebody confirm me that the above is a *correct* usage of rb_gc_register_address()? As said before, in my tests it works (it avoids GC). BTW I would also like to know whether both rb_gc_register_address() and rb_gc_unregister_address() can be called without the GVL. Really thanks a lot. PS: I'm already using rb_gc_mark() when the VALUE is attached to the C struct wrapped within a Ruby object, that's ok. But I "need" the above usage for the case of C data holding Ruby objects, without such a C data being "mapped" to a Ruby object. -- Iñaki Baz Castillo