[R] How to properly finalize external pointers?

Prof Brian Ripley ripley at stats.ox.ac.uk
Fri Aug 3 16:51:03 CEST 2007


On Fri, 3 Aug 2007, Duncan Murdoch wrote:

> On 8/3/2007 9:19 AM, Jens Oehlschlägel wrote:
>> Dear R .Call() insiders,
>>
>> Can someone enlighten me how to properly finalize external pointers in C code (R-2.5.1 win)? What is the relation between R_ClearExternalPtr and the finalizer set in R_RegisterCFinalizer?
>>
>> I succeeded registering a finalizer that works when an R object containing an external pointer is garbage collected. However, I have some difficulties figuring out how to do that in an explicit closing function.
>>
>> I observed that
>> - calling R_ClearExternalPtr does not trigger the finalizer and is dangerous because it removes the pointer before the finalizer needs it at garbage-collection-time (no finalization = memory leak)
>> - calling the finalizer directly ensures finalization but now the finalizer is called twice (once again at garbage collection time, and I did not find documentation how to unregister the finalizer)
>> - It works to delete the SEXP external pointer object but only if not calling R_ClearExternalPtr (but why then do we need it?) Furthermore it is unfortunate to delay freeing the external pointers memory if I know during runtime that it can be done immediately.
>>
>> Shouldn't R_ClearExternalPtr call the finalizer and then unregister it? 
>> (this would also work when removing the SEXP external pointer object is 
>> difficult because it was handed over to the closing function directly 
>> as a parameter)
>
> I think we want R_ClearExternalPtr to work even if the finalizer would
> fail (e.g. to clean up when there was an error when trying to build the
> external object).
>
> So I'd suggest that when you want to get rid of an external object
> immediately, you call the finalizer explicitly, then call
> R_ClearExternalPtr.  The documentation doesn't address the question of
> whether this will clear the registered finalizer so I don't know if
> you'll get a second call to the finalizer during garbage collection, but
> even if you do, isn't it easy enough to do nothing when you see the null
> ptr, as you do below?

You will get a further finalizer call at GC, and I know of no way to 
unregister finalizers. So make sure the finalizer does nothing the second 
time.

The way connections are handled in R-devel provides an example (although 
it is work in progress).

Another possibility is to call the GC yourself if you know there are a lot 
of objects to clear up.

> By the way, questions about programming at this level are better asked
> in the R-devel group.

Indeed.

[...]

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595


More information about the R-help mailing list