@@ -33,17 +33,19 @@ void standard_delete_finalizer(T* obj) {
33
33
34
34
template <typename T, void Finalizer (T*) >
35
35
void finalizer_wrapper(SEXP p) {
36
- if (TYPEOF (p) == EXTPTRSXP) {
37
- T* ptr = (T*) R_ExternalPtrAddr (p);
38
- RCPP_DEBUG_3 (" finalizer_wrapper<%s>(SEXP p = <%p>). ptr = %p" , DEMANGLE (T), p, ptr)
36
+ if (TYPEOF (p) != EXTPTRSXP)
37
+ return ;
39
38
40
- // Clear before finalizing to avoid interesting behavior
41
- // like access of freed memory,
42
- // e.g. https://github.com/r-dbi/RPostgres/issues/167
43
- R_ClearExternalPtr (p);
39
+ T* ptr = (T*) R_ExternalPtrAddr (p);
40
+ RCPP_DEBUG_3 (" finalizer_wrapper<%s>(SEXP p = <%p>). ptr = %p" , DEMANGLE (T), p, ptr)
44
41
45
- Finalizer (ptr);
46
- }
42
+ if (ptr == NULL )
43
+ return ;
44
+
45
+ // Clear before finalizing to avoid behavior like access of freed memory
46
+ R_ClearExternalPtr (p);
47
+
48
+ Finalizer (ptr);
47
49
}
48
50
49
51
template <
@@ -181,9 +183,7 @@ class XPtr :
181
183
// need to be ready for a NULL external pointer value (our
182
184
// default C++ finalizer is since delete NULL is a no-op).
183
185
// This clears the external pointer just before calling the finalizer,
184
- // to avoid interesting behavior with co-dependent finalizers,
185
- // like access of freed memory,
186
- // e.g. https://github.com/r-dbi/RPostgres/issues/167.
186
+ // to avoid interesting behavior with co-dependent finalizers.
187
187
finalizer_wrapper<T,Finalizer>(Storage::get__ ());
188
188
}
189
189
}
0 commit comments