[Rcpp-devel] Error when handling default values
Dirk Eddelbuettel
edd at debian.org
Mon Feb 3 19:41:47 CET 2014
Hi Alessandro,
Briefly-ish as I am at work:
On 3 February 2014 at 19:17, Alessandro Mammana wrote:
| Hi all,
| once again I have a bug and no idea what I am doing wrong.
| I started to handle optional arguments directly at the C++ level, so
| that I don't have to write a wrapper function in R. The pattern below
| has always worked so far, but today it crashed. It was very hard to
| reproduce, It took ages to nail it down to the minimal example below.
|
|
| in a file:
|
| // [[Rcpp::export]]
| void reproduce_error(int n,
| SEXP ucs = R_NilValue,
| SEXP mConst = R_NilValue){
|
| if (Rf_isNull(ucs)){
| IntegerVector v1(n);
| IntegerVector v2(n);
| ucs = (SEXP) List::create(Named("map")=v1, Named("values")=v2);
Casts via (SEXP) may seem natural to you, but are not used in our code.
If you want to enforce a SEXP, use wrap:
ucs = wrap(List::create(Named("map")=v1, Named("values")=v2));
| }
| if (Rf_isNull(mConst)){
| NumericVector v1(n);
| mConst = (SEXP) v1;
Ditto.
| }
|
| List ucs_list(ucs);
Why? You already have ucs.
Did you check that ucs_list is what you expect it to be?
Dirk
| IntegerVector map = ucs_list["map"];
| Rcout << "before" << std::endl;
| IntegerVector uniqueCS = ucs_list["values"];
| Rcout << "after" << std::endl;
| NumericVector multinomConst(mConst);
| }
|
| from R's terminal:
|
| >library(microbenchmark)
| >sourceCpp("scratchpad.cpp")
| >microbenchmark(reproduce_error(1000000), times=100)
| before
| after
| before
| after
| before
| after
| before
| after
| before
| after
| before
| after
| before
| after
| before
| after
| before
| after
| before
| after
| before
| Error: not compatible with INTSXP
|
| What am I doing wrong?
| Do you have other ideas about how I could handle NULL values?
Yes, and I think there are plenty of example in our code and unit tests.
And if in doubt, look at 'Writing R Extension' and do it in plain C.
| Maybe I should avoid to rewrap the list in a SEXP, but this method
| allows me to write very little code and no need for an "else" after
| "if (Rf_isNull(ucs))"
|
| I think the problem has to do with the way R manages its memory.
| Correct me if I am wrong. If ucs was a normal stl container (with a
Well it isn't. It is a proxy class around an R object. We make them behave
like STL objects but they are _not_ STL objects. If you want those, create
those.
| particular NULL state), then when I do:
|
| ucs = (SEXP) List::create(Named("map")=v1, Named("values")=v2);
See above. I would not put faith in this.
| ucs becomes the owner of the list, and the list is the owner of
| vectors v1 and v2 (no idea if they are getting copied there by the
| way..., with stl vectors I guess they would get copied), so when ucs
| goes out of scope it tries to free the memory allocated for the list,
| and the list tries to free the memory allocated for v1 and v2.
|
| But because ucs is not a normal stl container, I guess I need some
| other rules of thumb to understand how I should manage memory.
|
| Thanks a lot in advance, and, don't get me wrong, I still love Rcpp :D
Trust me, we do too but it is picky at times. My preferred style is to copy
from examples. Not infrequently my own :)
Dirk
|
| --
| Alessandro Mammana, PhD Student
| Max Planck Institute for Molecular Genetics
| Ihnestraße 63-73
| D-14195 Berlin, Germany
| _______________________________________________
| 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
--
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
More information about the Rcpp-devel
mailing list