From hb at maths.lth.se  Mon Mar 27 13:21:51 2006
From: hb at maths.lth.se (Henrik Bengtsson)
Date: Mon, 27 Mar 2006 13:21:51 +0200
Subject: [Rd] Safe to UNPROTECT() when object is assigned to a list?
Message-ID: <59d7961d0603270321j3d8ab3c7wdc78ad42eae7b5ca@mail.gmail.com>

Hi,

I'm troubleshooting some native code on Windows that very occationally
(and semi-randomly) crashes R.  Already looked at "everything", I just
want to double check that it is safe to UNPROTECT() allocated
variables as soon as they are assigned to, say, a PROTECTed list.

>From (R v2.3.0) Section 5.7.1 "Handling the effects of garbage
collection" in "Writing R Extensions":

"In some cases it is necessary to keep better track of whether
protection is really needed. Be particularly aware of situations where
a large number of objects are generated. The pointer protection stack
has a fixed size (default 10,000) and can become full. It is not a
good idea then to just PROTECT everything in sight and UNPROTECT
several thousand objects at the end. It will almost invariably 
possible to either assign the objects as part of another object (which
automatically protects them) or unprotect them immediately after use."

BTW, should it say "...another [protected] object..."?

Example from "5.7.4 Attributes" illustrating my question:

     SEXP out(SEXP x, SEXP y)
     {
       R_len_t i, j, nx, ny;
       double tmp;
       SEXP ans, dim, dimnames;

       nx = length(x); ny = length(y);
       PROTECT(ans = allocVector(REALSXP, nx*ny));
       for(i = 0; i < nx; i++) {
         tmp = REAL(x)[i];
         for(j = 0; j < ny; j++)
           REAL(ans)[i + nx*j] = tmp * REAL(y)[j];
       }

       PROTECT(dim = allocVector(INTSXP, 2));
       INTEGER(dim)[0] = nx; INTEGER(dim)[1] = ny;
       setAttrib(ans, R_DimSymbol, dim);

       *** It is safe to do UNPROTECT(1) for 'dim' already here, correct? ***

       PROTECT(dimnames = allocVector(VECSXP, 2));
       SET_VECTOR_ELT(dimnames, 0, getAttrib(x, R_NamesSymbol));
       SET_VECTOR_ELT(dimnames, 1, getAttrib(y, R_NamesSymbol));
       setAttrib(ans, R_DimNamesSymbol, dimnames);

       UNPROTECT(3);
       return(ans);
     }

Thanks

/Henrik



[Rd] Safe to UNPROTECT() when object is assigned to a list?
Henrik Bengtsson