[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