Skip to content
Prev 11176 / 12125 Next

[R-pkg-devel] Replacement for SETLENGTH

I am trying to determine the best way to eliminate the use of SETLENGTH to truncate over allocated vectors in my package BAS to eliminate the NOTES about non-API calls in anticipation of R 4.5.0.
it looks like using 

    x = Rf_lengthgets(x, newsize);  
    SET_VECTOR_ELT(result, 0, x); 
    
before returning works to resize without a performance hit that incurs with a copy.  (will this always re-use the supplied object if newsize < old size?)

There is no mention in section 5.9.2 about the need for re-protection of the object,  but it seems to be mentioned in some packages as well as a really old thread about SET_LENGTH that looks like a  non-API MACRO to lengthgets, 

indeed if I call gc() and then rerun my test I have had some non-reproducible aborts in R Studio on my M3 Mac (caught once in R -d lldb)  

Do I need to do something more like 

PROTECT_INDEX ipx0;.
PROTECT_WITH_INDEX(x0 = allocVector(REALSXP, old_size), &ipx0);

PROTECT_INDEX ipx1;.
PROTECT_WITH_INDEX(x1 = allocVector(REALSXP, old_size), &ipx1);

# fill in values in x0 and  x1up to new_size (random) < old_size
...
REPROTECT(x0 = Rf_lengthgets(x0, new_size), ipx0);
REPROTECT(x1 = Rf_lengthgets(x1, new_size), ipx1);

SET_VECTOR_ELT(result, 0, x0);
SET_VECTOR_ELT(result, 1, x1);
...
UNPROTECT(2);   # or is this 4? 
return(result);


There is also a mention in WRE of R_PreserveObject and R_ReleaseObject -  

looking for advice if this is needed, or which approach is better/more stable to replace SETLENGTH?   (I have many many instances that need to be updated, so trying to get some clarity here before updating and running code through valgrind or other sanitizers to catch any memory issues before submitting an update to CRAN.

best,
Merlise