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) {
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)
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);
41
49
}
42
50
43
51
template <
@@ -174,10 +182,9 @@ class XPtr :
174
182
// Call the finalizer -- note that this implies that finalizers
175
183
// need to be ready for a NULL external pointer value (our
176
184
// 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.
177
187
finalizer_wrapper<T,Finalizer>(Storage::get__ ());
178
-
179
- // Clear the external pointer
180
- R_ClearExternalPtr (Storage::get__ ());
181
188
}
182
189
}
183
190
You can’t perform that action at this time.
0 commit comments