[Rcpp-devel] gc() calls destructor twice when both class and XPtr deleted
Michael Shvartsman
mshvarts at umich.edu
Mon Feb 11 19:55:35 CET 2013
Hi Dirk --
Thanks for the quick response. My design is (I think) textbook
aggregation -- in my case, A is a logger class and B is an experiment
class. The experiment calls methods from the logger, but the logger may
be active for more than one experiment so it can't be created inside it.
So I create the logger and pass a pointer to it into the experiment.
There are definitely other ways to design this, but this way doesn't
seem to be particularly unreasonable.
The basic goal is to create a C++ object on the R side (in this
case, the logger class) and pass it back down to the C++ side for later
use by another C++ object (the experiment class). I thought that XPtr
was the right way to do this (based on e.g.
http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-December/003214.html),
but I could be misunderstanding either XPtrs or the example in that
email. If there is a different way to pass down the Rcpp class and
unwrap it to arrive at a pointer to the underlying C++ class, it would
be great. Best,
Mike.
> Dirk Eddelbuettel <mailto:edd at debian.org>
> February 11, 2013 12:40 PM
> On 11 February 2013 at 12:16, Michael Shvartsman wrote:
> | Hi Rcpp-devel -
> |
> | In some of my code, I return an XPtr pointing to one C++ class
> | (e.g. class A) to the R side, and then pass it back down to the C++
> side
> | in the constructor of another class (e.g. class B, which needs
> access to
> | some methods in class A). If I rm() both class A and the pointer to it
> | on the R side (or they otherwise both go out of scope), then the
> garbage
> | collector calls the destructor of class A twice and attempts to free
> the
> | memory twice.
> |
> | Happens on OSX and Ubuntu with latest R and Rcpp. Is this intended
> | behavior? If yes, what's a recommended workaround? I can go into more
> | detail on why this is useful to my workflow if needed. Below is a
> | minimal example. Best,
>
> Thanks for sending a complete example -- very helpful.
>
> I will think about this some more, but my first gut reaction is that your
> design is wrong. You are essentially "just" using XPtr to get two
> references
> to the same memory, and then for all intends and purposes doing
>
> x = new Something;
> delete x;
> delete x;
>
> which also doesn't work. I have worked quite happily with XPtr in the
> past,
> and so have others. I have however not mixed them with Modules, I
> think, so
> maybe that enters.
>
> But I think the best answers to the "I hurts when I do this" remains "well
> then just don't it".
>
> And I may well have missed something here...
>
> Dirk
>
> |
> | Mike Shvartsman.
> |
> | -----
> | library(Rcpp)
> | library(inline)
> |
> | inc <- '
> | using namespace Rcpp;
> | class A{
> | public:
> | A();
> | ~A();
> | XPtr<A> getPtr();
> | };
> |
> | XPtr<A> A::getPtr(){
> | return(XPtr<A>(this));
> | }
> |
> | A::A(){
> | Rcout << "CTOR" << std::endl;
> | }
> |
> | A::~A(){
> | Rcout << "DTOR" << std::endl;
> | }
> |
> | RCPP_MODULE(mod){
> | class_<A>("A")
> | .constructor()
> | .method("getPtr", &A::getPtr)
> | ;
> | }
> | '
> |
> | func <- cxxfunction(signature(), include=inc, plugin='Rcpp')
> |
> | mod <- Module('mod', getDynLib(func))
> |
> |
> | A <- mod$A
> |
> | a <- new(A)
> | aPtr <- a$getPtr()
> | rm(a)
> | rm(aPtr)
> | gc()
> | -----
> |
> | _______________________________________________
> | Rcpp-devel mailing list
> | Rcpp-devel at lists.r-forge.r-project.org
> | https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>
> Michael Shvartsman <mailto:mshvarts at umich.edu>
> February 11, 2013 12:16 PM
> Hi Rcpp-devel -
>
> In some of my code, I return an XPtr pointing to one C++ class
> (e.g. class A) to the R side, and then pass it back down to the C++
> side in the constructor of another class (e.g. class B, which needs
> access to some methods in class A). If I rm() both class A and the
> pointer to it on the R side (or they otherwise both go out of scope),
> then the garbage collector calls the destructor of class A twice and
> attempts to free the memory twice.
>
> Happens on OSX and Ubuntu with latest R and Rcpp. Is this intended
> behavior? If yes, what's a recommended workaround? I can go into more
> detail on why this is useful to my workflow if needed. Below is a
> minimal example. Best,
>
> Mike Shvartsman.
>
> -----
> library(Rcpp)
> library(inline)
>
> inc <- '
> using namespace Rcpp;
> class A{
> public:
> A();
> ~A();
> XPtr<A> getPtr();
> };
>
> XPtr<A> A::getPtr(){
> return(XPtr<A>(this));
> }
>
> A::A(){
> Rcout << "CTOR" << std::endl;
> }
>
> A::~A(){
> Rcout << "DTOR" << std::endl;
> }
>
> RCPP_MODULE(mod){
> class_<A>("A")
> .constructor()
> .method("getPtr", &A::getPtr)
> ;
> }
> '
>
> func <- cxxfunction(signature(), include=inc, plugin='Rcpp')
>
> mod <- Module('mod', getDynLib(func))
>
>
> A <- mod$A
>
> a <- new(A)
> aPtr <- a$getPtr()
> rm(a)
> rm(aPtr)
> gc()
> -----
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130211/410bf71a/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: postbox-contact.jpg
Type: image/jpeg
Size: 1228 bytes
Desc: not available
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130211/410bf71a/attachment-0002.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: compose-unknown-contact.jpg
Type: image/jpeg
Size: 770 bytes
Desc: not available
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130211/410bf71a/attachment-0003.jpg>
More information about the Rcpp-devel
mailing list