From: William Djaja Tjokroaminata Date: 2002-10-23T22:59:49+09:00 Subject: Re: rb_gc_register_address problem Hi Paul, Paul Brannan wrote: > On Tue, Oct 22, 2002 at 11:57:05PM +0900, William Djaja Tjokroaminata wrote: > Note, though, that this is not exception-safe. vector::push_back can > throw an exception (std::bad_alloc). If it does, then str is left > allocated. One solution is to push a dummy onto the vector before > allocating memory. Using your helper fuction: > std::vector foo; > void func(int argc, VALUE * argv, VALUE self) { > foo.push_back(0); > foo[foo.length()-1] = create_str_from_rubystr (argv[0])); > } Actually if there is concern that str is left allocated, I am wondering why we have a vector of char* to begin with; isn't this mixing C++ with C? Why don't you just have a C array of char* or a vector of strings? For example, std::vector foo; void func(int argc, VALUE * argv, VALUE self) { foo.push_back(string (STR2CSTR(argv[0]))); } And when you need the char*, you just call the c_str() of each string element. > The solution we went with was to leave the memory allocation to Ruby. I > prefer to let Ruby's GC handle as much memory as possible, so that I > don't have to worry quite so hard about exception-safety. The only > exceptions to this rule I see are: > 1) If I have many objects being allocated, I allocate them myself > 2) If I have resources allocated other than memory (such as open files > or sockets), I also handle that myself. Probably we have different views on this. I think the Ruby source code is responsible for its own exception-safety and our C code must be responsible for its own exception-safety, no matter whether the error occurs on the C-part or the Ruby-part (such as when Ruby cannot get more memory). By letting Ruby's GC handle as much memory as possible, we are unnecessarily increasing the duty cycle of the Ruby GC, especially when the C-part is highly dynamic while the Ruby-part is not so dynamic. For "typical" application this may be fine, but the application may not scale well. >> 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. > I agree. This is particularly important if the API ever changes. It > also allows porting extensions easily to other languages. This is part > of the philosophy behind SWIG. I think you just mentioned the two most important Ruby C coding wisdows. My current mistake is that I rely too much on Ruby; my extension currently will not be easily ported to other languages, so I have been thinking of rewriting my extension from scratch. Regards, Bill