[R] How to grow an R object from C (.Call Interface)

Peter Dalgaard p.dalgaard at biostat.ku.dk
Fri Oct 31 15:02:38 CET 2003


"Jens Oehlschlägel" <joehl at gmx.de> writes:

> What is the best way to grow an R return object in writing a C function
> using the Rdefines.h macros.
> In my application, the final size of the return object is not known during
> construction. My understanding is that each time I grow an R object I have to
> use PROTECT() again, probably before UNPROTECTing the smaller version.
> However, due to the stack character of the PROTECT mechanism, UNPROTECT would not
> work to remove the smaller one, after the bigger has been protected. Is this
> an indication to use UNPROTECT_PTR ? Or is another approach recommended?
> 
> May be the solution to this is worth a sentence in "Wrtiting R Extensions".
> 
> Thanks for any help

It depends on the kind of object, I'll assume we're talking vector
objects here. If you're *extending* an existing object (the new object
becomes part of the old object) matters are quite different.

I think you are looking for the PROTECT_WITH_INDEX and REPROTECT
mechanism that Luke added (I almost said "recently", but it was
in fact three years ago!). If that is not in the manual, it should
be. 

UNPROTECT_PTR is older and solves a similar problem, but where the
routine that unprotects is not the same as the one that protects (this
happens a lot in the parser code) and you cannot be sure that it is
the top item that needs to be removed. UNPROTECT_PTR works by
searching the stack for the pointer, pulling the record out of the
stack, and dropping every stack element on top of it. In contrast
REPROTECT knows which record to extract and just changes the pointer
value in it. I.e. UNPROTECT_PTR is potentially much less efficient,
although I don't think there are practical cases where more than an
handful of items have been pushed on the stack (the usual cases are
zero or one).

Also remember not to call any routine that could trigger a garbage
collection while you need access to both the old and the new extended
object. So, allocate, copy, reprotect, and *then* start computing new
entries. 

-- 
   O__  ---- Peter Dalgaard             Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics     2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark      Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk)             FAX: (+45) 35327907




More information about the R-help mailing list