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.
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@lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

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@lists.r-forge.r-project.org
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to