On Apr 20, 2010, at 10:12 AM, Simon Urbanek wrote:

> 
> On Apr 19, 2010, at 1:22 PM, Seth Falcon 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).
>> 
> 
> Can you elaborate on that? (It's really tricky to test this since you cannot 
> attach a finalizer to the allocated memory).
> 
> AFAICT the R_alloc allocates a regular R vector (raw or real depending on 
> size) so the usual R object rules apply. Then it is attached to the VStack. 
> If you also assign it to any other object accessible from the GC roots 
> (before the VStack goes away) then even removing the VStack entry won't cause 
> de-allocation because it will be flagged from the other root at mark time so 
> it won't be garbage collected. VStack is not released blindly it is simply 
> pruned and left to garbage collection to decide whether to release the 
> objects or not.
> 

Ah, I now see the issue - I missed the part that you're NOT using it as SEXP 
(tag/prot) in the EXTPTR but as void pointer in which case it is not traversed 
at GC time - point taken. If you assign it as SEXP anywhere (list, vector, 
etc.) then my point remains ;). But, again, use PROTECT(allocVector(RAWSXP, 
..)) for the same yet safe effect.

Cheers,
Simon


> That said, the lesson to Melissa is that you can simply allocate a raw vector 
> with the same effect - there is no need to use R_alloc() in her case (is user 
> code PROTECTing is sort of equivalent to the VStack used internally).
> 
> Cheers,
> Simon
> 
> 
> 
>> 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
> 
> 

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to