Skip to content

Commit 6ac9a0f

Browse files
committed
R and C integration gc()
1 parent e139f96 commit 6ac9a0f

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

src/rapi.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
6381
SEXP 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-
255272
SEXP R_ForestPredict(
256273
SEXP forestPtr,
257274
SEXP designMatrix)
@@ -280,20 +297,17 @@ SEXP R_ForestPredict(
280297
return predictedR;
281298
}
282299

283-
284300
SEXP 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-
297311
SEXP R_LoadRforce(
298312
SEXP path)
299313
{
@@ -306,11 +320,11 @@ SEXP R_LoadRforce(
306320
return forestPtr;
307321
}
308322

309-
310323
SEXP 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

Comments
 (0)