Henrik Bengtsson
2006-Mar-27 11:21 UTC
[Rd] Safe to UNPROTECT() when object is assigned to a list?
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 garbagecollection" 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
Peter Dalgaard
2006-Mar-27 12:54 UTC
[Rd] Safe to UNPROTECT() when object is assigned to a list?
"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