From p.dalgaard at biostat.ku.dk  Mon Mar 27 14:54:37 2006
From: p.dalgaard at biostat.ku.dk (Peter Dalgaard)
Date: 27 Mar 2006 14:54:37 +0200
Subject: [Rd] Safe to UNPROTECT() when object is assigned to a list?
In-Reply-To: <59d7961d0603270321j3d8ab3c7wdc78ad42eae7b5ca@mail.gmail.com>
References: <59d7961d0603270321j3d8ab3c7wdc78ad42eae7b5ca@mail.gmail.com>
Message-ID: <x2veu06oaa.fsf@viggo.kubism.ku.dk>

"Henrik Bengtsson" <hb at maths.lth.se> writes:

> 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..."?

Yes. (And the text could need general rephrasing too. I'm afraid that
I'm the guilty party.)

 
> 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? ***

Yes. The protection of "ans" will carry over to its attributes. 

>        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
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 

-- 
   O__  ---- Peter Dalgaard             ?ster Farimagsgade 5, Entr.B
  c/ /'_ --- Dept. of Biostatistics     PO Box 2099, 1014 Cph. K
 (*) \(*) -- University of Copenhagen   Denmark          Ph:  (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk)                  FAX: (+45) 35327907



[Rd] Safe to UNPROTECT() when object is assigned to a list?
Peter Dalgaard