Thank you very much. I think I do have a clearer understanding, but I have a few questions
On May 23, 2006, at 12:55 AM, Prof Brian Ripley wrote: > On Tue, 23 May 2006, Prof Brian Ripley wrote: > >> On Mon, 22 May 2006, Kasper Daniel Hansen wrote: >> >>> I have a few simple questions about the usage of PROTECT, more >>> specifically how careful one needs to be. Simple yes/no answers are >>> fine. >> >> (Except that in the last case they would be misleading.) >> >>> Most of the uses I have seen do protection when memory is allocated. >>> But what if one just want to assign a value of another function to a >>> variable. Say eg. that foo is a function that returns a SEXP. Would >>> the following code be fine? >>> >>> SEXP bar; >>> PROTECT(bar = foo()); >> >> It would be fine but may be unnecessary. It is objects and not >> pointers >> which are protected, and a SEXP is a pointer. So protection is >> needed >> only if foo() might return a pointer to an unprotected object. Ok. I have been coding foo in such a way that I unprotect everything in foo just before returning its value. I thought that was the "standard" way to do - is that true? Or should I leave the return value protected and then unprotect in the function calling foo? >>> Also, basically in one use case I would want to return the value of >>> foo immediately, but I need to do some cleaning up first, which has >>> nothing to do with R (more specifically, I need to close various >>> files). Would I then need to protect foo, as in >>> >>> SEXP bar; >>> bar = foo(); >>> "close the file in C++" >>> return bar; >> >> Fine, as PROTECT protects against R garbage collection, and that >> can only >> happen if R's functions are called. >> >>> Finally, I am also assigning values to the components of a list. >>> Would the following be ok >>> >>> SEXP bar; >>> PROTECT(bar = NEW_LIST(2)); >>> SET_VECTOR_ELT(bar, 0, ScalarInteger(test()); >>> >>> (where test is a function returning int, which again has nothing to >>> do with R - it interfaces to an extern library), or do I need to >>> hedge myself against garbage collection in the SET_VECTOR_ELT macro? >> >> You do need to protect but elsewhere in this call, as >> ScalarInteger does >> memory allocation: >> >> INLINE_FUN SEXP ScalarInteger(int x) >> { >> SEXP ans = allocVector(INTSXP, 1); >> INTEGER(ans)[0] = x; >> return ans; >> } >> >> but SET_VECTOR_ELT does not. So you need >> >> SEXP bar, tmp; >> PROTECT(bar = NEW_LIST(2)); >> PROTECT(tmp = test()); >> SET_VECTOR_ELT(bar, 0, ScalarInteger(tmp)); >> UNPROTECT(1); > > Or a design that uses fewer PROTECTs > > SEXP bar, tmp; > PROTECT(bar = allocVector(VECSXP, 2)); > tmp = allocVector(INTSXP, 1); > SET_VECTOR_ELT(bar, 0, tmp); > INTEGER(tmp)[0] = test(); I thought I got this. Then I grepped the sources and found this in main/platform.c: PROTECT(ans = allocVector(VECSXP, 18)); PROTECT(nms = allocVector(STRSXP, 18)); SET_STRING_ELT(nms, 0, mkChar("double.eps")); SET_VECTOR_ELT(ans, 0, ScalarReal(R_AccuracyInfo.eps)); This looks very similar to what I did above. In my case "test" was a C ++ function coming from outside of R returning an int. That was perhaps not clear from my original mail, since the first suggested correction had PROTECT(tmp = test()); indicating that the return value for test is a SEXP. Or am I completely of? I have tried running my original suggestion with gctorture(TRUE) and it did not give any errors. But neither did the second suggested correction. Thanks, Kasper > -- > Brian D. Ripley, [EMAIL PROTECTED] > Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ > University of Oxford, Tel: +44 1865 272861 (self) > 1 South Parks Road, +44 1865 272866 (PA) > Oxford OX1 3TG, UK Fax: +44 1865 272595 ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel