[Rcpp-devel] gc() calls destructor twice when both class and XPtr deleted
Yan Zhou
zhouyan at me.com
Mon Feb 11 20:10:41 CET 2013
It seems to me that XPtr is like an ownership pointer. It is much like unique_ptr. What you need here is a non-owning reference pointer, like weak_ptr.
Have you tried
XPtr<A> A::getPtr(){
return(XPtr<A>(this, false));
}
With the optional argument, a finalizer is not set and the gc will not delete the C++ object. I haven't used XPtr in this way, but from the document I guess this shall work.
Best,
Yan Zhou
On Feb 11, 2013, at 6:55 PM, Michael Shvartsman <mshvarts at umich.edu> wrote:
> 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 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 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()
>> -----
>>
> _______________________________________________
> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130211/2aa7f16a/attachment.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/2aa7f16a/attachment.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/2aa7f16a/attachment-0001.jpg>
More information about the Rcpp-devel
mailing list