Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions inst/include/Rcpp/XPtr.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,19 @@ void standard_delete_finalizer(T* obj) {

template <typename T, void Finalizer(T*) >
void finalizer_wrapper(SEXP p) {
if (TYPEOF(p) == EXTPTRSXP) {
T* ptr = (T*) R_ExternalPtrAddr(p);
RCPP_DEBUG_3("finalizer_wrapper<%s>(SEXP p = <%p>). ptr = %p", DEMANGLE(T), p, ptr)
Finalizer(ptr);
}
if (TYPEOF(p) != EXTPTRSXP)
return;

T* ptr = (T*) R_ExternalPtrAddr(p);
RCPP_DEBUG_3("finalizer_wrapper<%s>(SEXP p = <%p>). ptr = %p", DEMANGLE(T), p, ptr)

if (ptr == NULL)
return;

// Clear before finalizing to avoid behavior like access of freed memory
R_ClearExternalPtr(p);

Finalizer(ptr);
}

template <
Expand Down Expand Up @@ -174,10 +182,9 @@ class XPtr :
// Call the finalizer -- note that this implies that finalizers
// need to be ready for a NULL external pointer value (our
// default C++ finalizer is since delete NULL is a no-op).
// This clears the external pointer just before calling the finalizer,
// to avoid interesting behavior with co-dependent finalizers.
finalizer_wrapper<T,Finalizer>(Storage::get__());

// Clear the external pointer
R_ClearExternalPtr(Storage::get__());
}
}

Expand Down