[R] Destructor for S4 objects?

Adam Lyon lyon at fnal.gov
Wed Jan 12 01:10:31 CET 2005


Hi Robert,

It looks like there is no way to explicitly make an S4 object call a
function when it is garbage collected unless you resort to tricks with
reg.finalizer.

It turns out that Prof. Ripley's reply (thanks!!) had enough hints in it
that I was able to get the effect I wanted by using R's external pointer
facility. In fact it works quite nicely.

In a nutshell, I create a C++ object (with new) and then wrap its pointer
with an R external pointer using
SEXP rExtPtr = R_MakeExternalPtr( cPtr, aTag, R_NilValue);

Where cPtr is the C++/C pointer to the object and aTag is an R symbol
describing the pointer type [e.g. SEXP aTag =
install("this_is_a_tag_for_a_pointer_to_my_object")]. The final argument is
"a value to protect". I don't know what this means, but all of the examples
I saw use R_NilValue.

If you want a C++ function to be called when R loses the reference to the
external pointer (actually when R garbage collects it, or when R quits), do
R_RegisterCFinalizerEx( rExtPtr, (R_CFinalizer_t)functionToBeCalled, TRUE );

The TRUE means that R will call the "functionToBeCalled" if the pointer is
still around when R quits. I guess if you set it to FALSE, then you are
assuming that your shell can delete memory and/or release resources when R
quits. 

So return this external pointer to R (the function that new'ed it was called
by .Call or something similar) and stick it in a slot of your object. Then
when your object is garbage collected, "functionToBeCalled" will be called.
The slot would have the type "externalptr".

The functionToBeCalled contains the code to delete the C++ pointer or
release resources, for example...

SEXP functionToBeCalled( SEXP rExtPtr ) {
  // Get the C++ pointer
  MyThing* ptr = R_ExternalPtrAddr(rExtPtr);

  // Delete it
  delete ptr;

  // Clear the external pointer
  R_ClearExternalPtr(rExtPtr);

  return R_NilValue;
}

And there you have it.

There doesn't seem to be any official documentation on this stuff (at least
none that I could find). The best references I found are on the R developers
web page. See the links within  "some notes on _references, external
objects, or mutable state_ for R and a _simple implementation_ of external
references and finalization". Note that the documents are slightly out of
date (the function names have apparently been changed somewhat). The latter
one has some examples that are very helpful. And as Prof. Ripley pointed
out, RODBC uses this facility too, so look at that code.

Hope this was useful. Good luck.

--- Adam

Adam Lyon (lyon-at-fnal.gov)
Fermi National Accelerator Laboratory
Computing Division / D0 Experiment




More information about the R-help mailing list