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.
> 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);
--
Brian D. Ripley, ripley at stats.ox.ac.uk
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