@@ -60,6 +60,24 @@ void SaveTreeArray(
6060 }
6161}
6262
63+ // Finalizer must have type void (*)(SEXP)
64+ static void forest_finalizer (SEXP ext )
65+ {
66+ // Get the C pointer stored in the external pointer
67+ RandomSurvivalForest * forest = (RandomSurvivalForest * )R_ExternalPtrAddr (ext );
68+ if (forest == NULL )
69+ {
70+ // Already cleared or never set; nothing to do
71+ return ;
72+ }
73+
74+ // Free the underlying C object
75+ FreeSurvivalForest (forest );
76+
77+ // Clear the external pointer so we can't double-free
78+ R_ClearExternalPtr (ext );
79+ }
80+
6381SEXP R_Rforce (
6482 SEXP splitFunctionIndex ,
6583 SEXP interaction ,
@@ -119,7 +137,7 @@ SEXP R_Rforce(
119137 _treePhi is a 2D array of size nTrees * nUnits, a global variable split.h::34
120138 it is updated automatically in forest.c
121139 has to be allocated before calling the RandomForest function
122- **************************/
140+ **************************/
123141 _treePhi = Allocate2DArray (nTrees0 , nUnits );
124142
125143 switch (splitFunctionIndex0 )
@@ -129,7 +147,7 @@ SEXP R_Rforce(
129147 leafOutputFunction = LeafOutputInterval ;
130148 lenOutput = nUnits ;
131149 _pseudoRisk2 = 1L ;
132- _phi2 = 1L ;
150+ _phi2 = 1L ;
133151 _longformat = 0L ;
134152 _gee = 0L ;
135153 break ;
@@ -157,7 +175,7 @@ SEXP R_Rforce(
157175 }
158176
159177 // whether to account for interaction in gee split rule
160- _interaction = (INTEGER (interaction )[0 ] == 1 ) ? 1 : 0 ;
178+ _interaction = (INTEGER (interaction )[0 ] == 1 ) ? 1 : 0 ;
161179 ncolsDesign = ncolsDesign - lenOutput ;
162180
163181 // call the function
@@ -206,7 +224,7 @@ SEXP R_Rforce(
206224 // return the forest to R
207225 // create an external pointer to the forest
208226 SEXP forestPtr = PROTECT (R_MakeExternalPtr (forest , R_NilValue , R_NilValue ));
209- R_RegisterCFinalizerEx (forestPtr , ( R_CFinalizer_t ) FreeSurvivalForest , TRUE);
227+ R_RegisterCFinalizerEx (forestPtr , forest_finalizer , TRUE);
210228 // bag matrix: nTrees * nrow
211229 SEXP bagMatrix = IntPtrToRMatrix (forest -> bagMatrix , nTrees0 , nrow );
212230 // tree_phi: nTrees * lenOutput
@@ -220,7 +238,7 @@ SEXP R_Rforce(
220238 // oobPredicted: nrow * lenOutput
221239 SEXP oobPredicted = DoublePtrToRMatrix (forest -> oobPredicted , nrow , lenOutput );
222240 // likelihoodsum: 1 * nTrees
223-
241+
224242 // free the memory
225243 // FreeSurvivalForest(forest);
226244 free (nNodes );
@@ -251,7 +269,6 @@ SEXP R_Rforce(
251269 return list ;
252270}
253271
254-
255272SEXP R_ForestPredict (
256273 SEXP forestPtr ,
257274 SEXP designMatrix )
@@ -280,20 +297,17 @@ SEXP R_ForestPredict(
280297 return predictedR ;
281298}
282299
283-
284300SEXP R_SaveRforce (
285301 SEXP forestPtr ,
286302 SEXP path )
287303{
288304 SaveSurvivalForest (
289305 (RandomSurvivalForest * )R_ExternalPtrAddr (forestPtr ),
290- CHAR (STRING_ELT (path , 0 ))
291- );
306+ CHAR (STRING_ELT (path , 0 )));
292307
293308 return R_NilValue ;
294309}
295310
296-
297311SEXP R_LoadRforce (
298312 SEXP path )
299313{
@@ -306,11 +320,11 @@ SEXP R_LoadRforce(
306320 return forestPtr ;
307321}
308322
309-
310323SEXP R_PrintTree (
311324 SEXP forestPtr ,
312325 SEXP treeIndex ,
313- SEXP filename ) {
326+ SEXP filename )
327+ {
314328 // convert the forest pointer to C pointer
315329 RandomSurvivalForest * forest = (RandomSurvivalForest * )R_ExternalPtrAddr (forestPtr );
316330 if (forest == NULL )
@@ -324,8 +338,8 @@ SEXP R_PrintTree(
324338 Rf_error ("Invalid tree index." );
325339 }
326340
327- char * filename0 = (char * ) CHAR (STRING_ELT (filename , 0 ));
341+ char * filename0 = (char * )CHAR (STRING_ELT (filename , 0 ));
328342 WriteTreeDotFile (forest -> forest [treeIndex0 ], filename0 );
329-
343+
330344 return R_NilValue ;
331345}
0 commit comments