Thanks for the responses. Seth's example is indeed what I was trying (hoping) to do, it seems to work on my system fine (ubuntu x86_64, R 2.10.1). But if it doesn't work for him, then that definitely answers my question. I guess I'll have to go the Calloc/Free route. Thanks, Melissa
On Mon, Apr 19, 2010 at 1:22 PM, Seth Falcon <s...@userprimary.net> wrote: > On 4/19/10 8:59 AM, Simon Urbanek wrote: >> >> On Apr 19, 2010, at 10:39 AM, Melissa Jane Hubisz wrote: >> >>> Hello, >>> The Writing R extensions manual section 6.1.1 describes the transient >>> memory allocation function R_alloc, and states that memory allocated >>> by R_alloc is automatically freed after the .C or .Call function is >>> completed. However, based on my understanding of R's memory handling, >>> as well as some test functions I have written, I suspect that this is >>> not quite accurate. If the .Call function returns an external pointer >>> to something created with R_alloc, then this object seems to stick >>> around after the .Call function is completed, and is subject to >>> garbage collection once the external pointer object is removed. >>> >> > >> Yes, because the regular rules for the lifetime of an R object apply >> since it is in fact an R object. It is subject to garbage collection >> so if you assign it anywhere its lifetime will be tied to that object >> (in your example EXTPTRSXP). > > I may be misunderstanding the question, but I think the answer is actually > that it is *not* safe to put memory allocated via R_alloc into the external > pointer address of an EXTPTRSXP. > > Here's what I think Melissa is doing: > > SEXP make_test_xp(SEXP s) > { > SEXP ans; > const char *s0 = CHAR(STRING_ELT(s, 0)); > char *buf = (char *)R_alloc(strlen(s0) + 1, sizeof(char)); > memcpy(buf, s0, strlen(s0) + 1); > ans = R_MakeExternalPtr(buf, R_NilValue, R_NilValue); > return ans; > } > > The memory allocated by R_alloc is "released" at the end of the .Call via > vmaxset(vmax). Using R_alloc in this way will lead to memory corruption (it > does for me when I made a simple test case). > > For memory that really is external (not SEXP), then you should instead use > Calloc and register a finalizer for the external pointer that will do any > required cleanup and then call Free. > > If instead you want to have an externally managed SEXP, you could put it in > the protected slot of the external pointer, but then you should allocate it > using standard R allocation functions. > > > > + seth > > -- > Seth Falcon | @sfalcon | http://userprimary.net/ > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel