[R] return tree from .Call

Prof Brian Ripley ripley at stats.ox.ac.uk
Tue Aug 22 08:44:55 CEST 2006


Please see the posting guide: low-level programming questions to R-devel.

On Mon, 21 Aug 2006, Sender wrote:

> Hello:
> 
> I was hoping to get some advice about how to return a tree (basically a
> linked list -- with each node containing a parent, left, and right  node
> pointers) from a C routine back into R. Each node itself contains several
> attributes (a double, a char *, an int, and a void * )
> 
> Initially I was thinking I could just return to R a SEXP containing a
> pointer to the Root Node, but then realized that the pointer would be
> useless since C probably frees the memory after I leave the routine.

That's not true in general: it depends how you allocated them.  With 
malloc, you need to do a free.  External pointer types and finalizers are 
available for just this, and you can also use the memory of R structures.

> Since trees vary in length (or height) I need to be able to loop thru the
> tree until all Nodes have been visited and saved in a SEXP. I'm really new
> to handling R objects from within C, and converting and returning a large
> tree structure is daunting. Here is some rough code I was thinking about
> using to do this.  Any suggestions or help will be greatly appreciated!

Since elements of a protected list are protected, you can simplify the use 
of PROTECTs (and may have to in order to avoid overflows) by linking into 
a list at allocation time.  Do node first, then its elements.

> SEXP list ;
> 
> PROTECT( list = allocVector(VECSXP, tree->size) ) ;
> 
> for( i = 0; i < tree->size; ++i ){
>      SEXP node, tree_double, tree_char, tree_int, tree_voidPTR ;
> 
>      PROTECT( tree_double = NEW_NUMERIC( tree->weight ) ) ;
>      PROTECT( tree_char = NEW_CHARACTER( tree->name ) ) ;
>      PROTECT( tree_int = NEW_INTEGER( tree->exons ) ) ;
>      PROTECT( tree_voidPTR = NEW_CHARACTER( tree->data ) ) ;   ??? not sure
> about this...
> 
>      PROTECT( node = allocVector( VECSXP, 4 ) ) ;
>      SET_VECTOR_ELT( node, 0, tree_double) ;
>      SET_VECTOR_ELT( node, 1, tree_char) ;
>      SET_VECTOR_ELT( node, 2, tree_int) ;
>      SET_VECTOR_ELT( node, 3, tree_voidPTR ) ;
> 
>      SET_VECTOR_ELT( list, i, node ) ;
> }
> 
> UNPROTECT( tree->size * 4 ) ;  ??? Tricky..
> return( list ) ;
> 
> Look reasonable ?
> 
> THANKS !
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
> 

-- 
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



More information about the R-help mailing list