File tree Expand file tree Collapse file tree 1 file changed +15
-8
lines changed
Expand file tree Collapse file tree 1 file changed +15
-8
lines changed Original file line number Diff line number Diff line change @@ -33,11 +33,19 @@ void standard_delete_finalizer(T* obj) {
3333
3434template <typename T, void Finalizer (T*) >
3535void 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)
39- Finalizer (ptr);
40- }
36+ if (TYPEOF (p) != EXTPTRSXP)
37+ return ;
38+
39+ T* ptr = (T*) R_ExternalPtrAddr (p);
40+ RCPP_DEBUG_3 (" finalizer_wrapper<%s>(SEXP p = <%p>). ptr = %p" , DEMANGLE (T), p, ptr)
41+
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);
4149}
4250
4351template <
@@ -174,10 +182,9 @@ class XPtr :
174182 // Call the finalizer -- note that this implies that finalizers
175183 // need to be ready for a NULL external pointer value (our
176184 // default C++ finalizer is since delete NULL is a no-op).
185+ // This clears the external pointer just before calling the finalizer,
186+ // to avoid interesting behavior with co-dependent finalizers.
177187 finalizer_wrapper<T,Finalizer>(Storage::get__ ());
178-
179- // Clear the external pointer
180- R_ClearExternalPtr (Storage::get__ ());
181188 }
182189 }
183190
You can’t perform that action at this time.
0 commit comments