[Rcpp-devel] Passing a pointer to a class via modules
Ege Rubak
rubak at math.aau.dk
Sun Feb 5 09:36:39 CET 2017
Hi,
I'm making an R interface to Google's s2 library for geometry on the
sphere via Rcpp Modules. In general Modules is great for this since it
allows me to expose a lot of classes and functions without much C++
experience.
Now I have encountered a problem which I would be grateful for help on.
Context: A S2Polygon is a region on the sphere consisting of one or more
loops (of class S2Loop) which may represent e.g. landmass and lakes.
I have successfully exposed these classes using RCPP_EXPOSED_CLASS, and
everything appears to work, but then at some later point when I try to
access the loop in the polygon I suddenly get segfaults like:
*** caught segfault ***
address 0x111, cause 'memory not mapped'
An irrecoverable exception occurred. R is aborting now ...
I think that this happens because the S2Polygon doesn't contain the
loops that it is made up from but only pointers to these, and it appears
that when I pass a S2Loop to the S2Polygon (through a S2PolygonBuilder)
a new copy of the loop is made in C++ land and the S2Polygon points to
this copy (and I guess eventually it is destroyed since it isn't
protected by R).
I can construct a S2Loop from a data.frame of (lng,lat)s:
```r
library(s2) ## Version from github.com/spatstat/s2 -- not CRAN!
template <- data.frame(lng = c(1,-1,-1,1), lat = c(1,1,-1,-1))
s2loop <- S2Loop$new(template)
```
Then a S2Polygon can be constructed using a builder like this:
```r
pb <- S2PolygonBuilder$new(S2PolygonBuilderOptions$new())
pb$AddLoop(s2loop)
p <- S2Polygon$new()
unused_edges <- 0
pb$AssemblePolygon(p, unused_edges)
```
The polygon `p` now has a single loop, but this loop is not pointing to
the one in R as I see output like:
```r
s2loop
## C++ object <0x23c9620> of class 'S2Loop' <0x27a80d0>
p$loop(0)
## C++ object <0xe8a9c0> of class 'S2Loop' <0x27a80d0>
```
In s2polygonbuilder.h the member function AddLoop(S2Loop const* loop)
doesn't take ownership over the loop according to the source code comment:
https://github.com/spatstat/s2/blob/master/src/geometry/s2/s2polygonbuilder.h#L192-L193
Do you think I have the correct understanding of the problem?
And more importantly do you see a way to fix it? (Which is an
non-intrusive as possible, since I try to modify the source code as
little as possible.)
At the bottom of this email is a short script creating a bigger polygon
from many loops and then accessing the loops, which consistently
triggers the segfault for me in case it has any interest (probably not
since it takes several minutes to just install the library from GitHub,
so I don't expect anyone to waste time on this).
Kind regards,
Ege
############### segfault.R ###############
```r
library(s2) ## Version from github.com/spatstat/s2 -- not CRAN!
template <- data.frame(lng = c(1,-1,-1,1), lat = c(1,1,-1,-1))
looplist <- lapply(1:80, function(s) s*template)
s2loops <- lapply(looplist, S2Loop$new)
pb <- S2PolygonBuilder$new(S2PolygonBuilderOptions$new())
for(l in s2loops) pb$AddLoop(l)
p <- S2Polygon$new()
unused_edges <- 0
pb$AssemblePolygon(p, unused_edges)
p$loop(0)
for(i in 1:p$num_loops()){
p$loop(i-1)
}
```
#############################################
--
Ege Rubak, Associate Professor,
Department of Mathematical Sciences, Aalborg University
Fredrik Bajers Vej 7G, 9220 Aalborg East, Denmark
Phone: (+45)99408861
Mobile: (+45)30230252
Email: rubak at math.aau.dk
More information about the Rcpp-devel
mailing list