[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
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.
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