[Rcpp-devel] Error when handling default values

Kevin Ushey kevinushey at gmail.com
Mon Feb 3 19:27:37 CET 2014


When I run this (with latest CRAN Rcpp, 0.11.0), I get the error:

    Error: index out of bounds

My best guess: you are casting things to SEXP, which removes the
protection guarantees that Rcpp offers you, and so these objects are
getting gc'ed without you expecting it.

IIUC, casting with (SEXP) calls the conversion operator, which just
returns the underlying SEXP, and destructs the old List object, which
also cleans up the protection stack (leaving that SEXP now
unprotected).

Try using different Rcpp containers (for example, RObject in place of
SEXP). Don't use SEXPs unless you understand the underlying protection
mechanism, or are prepared to protect and unprotect the objects as
needed. Shield<SEXP> is also an option if you want a raw SEXP but with
protection guarantees.

I'm not sure why you need a SEXP, since all functions from the R API
should work on Rcpp containers. Rf_isNull will still operate even if
you use a List or NumericVector or ...

Cheers,
Kevin

On Mon, Feb 3, 2014 at 10:17 AM, Alessandro Mammana
<mammana at molgen.mpg.de> 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);
>     }
>     if (Rf_isNull(mConst)){
>         NumericVector v1(n);
>         mConst = (SEXP) v1;
>     }
>
>     List ucs_list(ucs);
>     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?
> 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
> particular NULL state), then when I do:
>
> ucs = (SEXP)  List::create(Named("map")=v1, Named("values")=v2);
>
> 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
>
>
> --
> 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


More information about the Rcpp-devel mailing list