Assume a C program invoked by .Call, that returns a list. Near the top of the program we allocate space for all the list elements. (It is my habit to use "xyz2" for the name of the R object and "xyz" for the pointer to its contents.) PROTECT(means2 = allocVector(REALSXP, nvar)); means = REAL(means2); PROTECT(u2 = allocVector(REALSXP, nvar)); u = REAL(u2); PROTECT(loglik2 = allocVector(REALSXP, 2)); loglik = REAL(loglik2); PROTECT(rlist = mknamed(VECSXP, outnames)); Can I assign the individual elements into rlist using SET_VECTOR_ELT at this point, or do I need to wait until the end of the program, after I've filled in means[i], u[i], etc.? I likely depends on whether I'm assigning a pointer or a copy. Terry T.
On Apr 1, 2013, at 1:10 PM, Terry Therneau wrote:> Assume a C program invoked by .Call, that returns a list. > > Near the top of the program we allocate space for all the list elements. (It is my habit to use "xyz2" for the name of the R object and "xyz" for the pointer to its contents.) > > PROTECT(means2 = allocVector(REALSXP, nvar)); > means = REAL(means2); > PROTECT(u2 = allocVector(REALSXP, nvar)); > u = REAL(u2); > PROTECT(loglik2 = allocVector(REALSXP, 2)); > loglik = REAL(loglik2); > > PROTECT(rlist = mknamed(VECSXP, outnames)); > > Can I assign the individual elements into rlist using SET_VECTOR_ELT at this point, or do I need to wait until the end of the program, after I've filled in means[i], u[i], etc.? I likely depends on whether I'm assigning a pointer or a copy. >You're assigning a pointer, so it doesn't matter. FWIW, you can avoid all the PROTECTion mess if you alloc+assign, e.g. SEXP rlist = PROTECT(mknamed(VECSXP, outnames)); SEXP means = SET_VECTOR_ELT(rlist, 0, allocVector(REALSXP, nvar)); ... since you only need to protect the parent object. Cheers, Simon
On 01/04/2013 1:10 PM, Terry Therneau wrote:> Assume a C program invoked by .Call, that returns a list. > > Near the top of the program we allocate space for all the list elements. (It is my habit > to use "xyz2" for the name of the R object and "xyz" for the pointer to its contents.) > > PROTECT(means2 = allocVector(REALSXP, nvar)); > means = REAL(means2); > PROTECT(u2 = allocVector(REALSXP, nvar)); > u = REAL(u2); > PROTECT(loglik2 = allocVector(REALSXP, 2)); > loglik = REAL(loglik2); > > PROTECT(rlist = mknamed(VECSXP, outnames)); > > Can I assign the individual elements into rlist using SET_VECTOR_ELT at this point, or do > I need to wait until the end of the program, after I've filled in means[i], u[i], etc.? I > likely depends on whether I'm assigning a pointer or a copy.You could assign them at this point, but only if you're sure the pointers won't change. You might change the pointers if you reallocate a vector to lengthen it or shorten it, for example. Generally speaking this won't happen behind your back, but you might forget and do it in the future when you modify the function, so I'd say it's safer to wait until the last minute to put the pointers in the list. Duncan Murdoch