To make it harder for users to shoot themselves in the foot with
'List::create(Named("x") = wrap(X), ...', is it possible to make it simply
illegal to assign an explicit "wrap" to a "Named"? This would force everyone to
use implicit wraps, which as you said are safe.
Davor
On 2011-04-06, at 4:22 AM, Romain Francois wrote:
> Hmmmmmmmm. I'm afraid I can't fix this.
>
> Here is the story: both wrap(X) and wrap(X) create a new SEXP and allocate
> memory. When wrap(Y) is called, since the created object is large, R calls
> the GC to collect unprotected SEXP to free some space. So my guess is that at
> that point the SEXP that is generated by wrap(X) is collected since it is not
> protected.
>
> I can not deal with this inside ::create, because it is too late.
>
>
> A Workaround is to use this :
>
> return Rcpp::List::create(
> Rcpp::Named("X") = X,
> Rcpp::Named("Y") = Y
> );
>
> i.e. use the implicit wrap. here wrap will be called much later and things
> are fine.
>
>
> The issue is that when calling wrap it creates an unprotected SEXP, and Rcpp
> is not responsible for these. If the programmer passes an unprotected SEXP to
> ::create, it is his responsability to protect it. So another alternative
> would be:
>
> SEXP xx = PROTECT( wrap( X ) ) ;
> SEXP yy = PROTECT( wrap( Y ) ) ;
> Rcpp::List result = Rcpp::List::create(
> Rcpp::Named("X") = xx,
> Rcpp::Named("Y") = yy
> );
> UNPROTECT(2) ;
> return res ;
>
> yes, this is ugly.
>
> Romain
>
> Le 06/04/11 11:42, Romain Francois a écrit :
>>
>> Good news. I can reproduce it.
>> Bas news. This is likely a PROTECT problem with the Rcpp::List constructor.
>>
>> Wearing my bugbuster costume, and getting ready for a fight.
>>
>> Romain
>>
>> Le 07/03/11 23:03, "Günter J. Hitsch" a écrit :
>>>
>>> I'm new to Rcpp and RcppArmadillo---so far I like it a lot! Thanks to
>>> the developers for their good work.
>>>
>>> I run into a peculiar kind of problem when I try to pass a "large"
>>> Armadillo object back to R. Here's some code to replicate the problem in
>>> stylized form:
>>>
>>>
>>> extern "C" SEXP testFun(SEXP L_)
>>> {
>>> const long L = Rcpp::as<long>(L_);
>>> arma::mat X(L,1);
>>> arma::mat Y(L,1);
>>> X.fill(1);
>>> Y.fill(2);
>>> return Rcpp::List::create(
>>> Rcpp::Named("X") = Rcpp::wrap(X),
>>> Rcpp::Named("Y") = Rcpp::wrap(Y)
>>> );
>>> }
>>>
>>>
>>> I compile (both using g++ and the Intel Compiler --- choice of compiler
>>> makes no difference) and then call from R:
>>>
>>>
>>> L = 1000000
>>> ret = .Call("testFun", as.integer(L))
>>> print(ret$X[1:5,])
>>> print(ret$Y[1:5,])
>>>
>>>
>>> Here's what I often get as output:
>>>
>>> [1] 1 1 1 1 1
>>> [1] 1 1 1 1 1
>>>
>>> However, the second rows should be all 2's!
>>>
>>> When I try to pass smaller matrices, for example by setting L=100000,
>>> the problem goes away:
>>>
>>> [1] 1 1 1 1 1
>>> [1] 2 2 2 2 2
>>>
>>>
>>> Also, the problem does not arise when I create and pass pack objects of
>>> type Rcpp::NumericMatrix; so far I've see the problem only with
>>> Armadillo objects. I've encountered this on two Macs running OS X
>>> 10.6.6, R 2.12.2, and I'm using the latest versions of Rcpp and
>>> RcppArmadillo.
>>>
>>> Help on this matter is appreciated!
>>>
>>> Günter
>>>
>>>
>>>
>>> _______________________________________________
>>> Rcpp-devel mailing list
>>> [email protected]
>>> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>>
>>
>
>
> --
> Romain Francois
> Professional R Enthusiast
> +33(0) 6 28 91 30 30
> http://romainfrancois.blog.free.fr
> http://romain-francois.com
> |- http://bit.ly/fhqbRC : Rcpp workshop in Chicago on April 28th
> |- http://bit.ly/dFyZGB : Hydraulique au Montpellier Comedie Club
> `- http://bit.ly/eVXit9 : Eponyme : 40 minutes stand up
>
>
> _______________________________________________
> Rcpp-devel mailing list
> [email protected]
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
_______________________________________________
Rcpp-devel mailing list
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel