Re: [R] return tree from .Call

From: Prof Brian Ripley <ripley_at_stats.ox.ac.uk>
Date: Tue 22 Aug 2006 - 16:44:55 EST

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

______________________________________________
R-help@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.
Received on Tue Aug 22 17:05:16 2006

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.1.8, at Tue 22 Aug 2006 - 18:21:48 EST.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.