开发者

R .call() interface and EXTPTRSXP: Understanding PROTECT/UNPROTECT with externally allocated objects

In the following code, object of type foo is created with a call to foo_new() and an external-pointer to the object is returned to R. Subsequent computations are performed by passing ptr_foo. The object is eventually freed with an explicit call to foo_free(foo *X). All computations are performed by libfoo.

Does the fact that ptr_foo was created mean that all other dynamically allocated fields within the foo object are automatically protected? Or, is it possible that fields such as "bar" may be swept away by the garbage collector?

SEXP foo_开发者_JAVA百科new (SEXP n) {
    SEXP ptr_foo;
    foo *X = (foo*) foo_new( 1, sizeof(foo) );
    //foo is protected from garbage collection
    assert( X );
    X->bar = (int*) foo_add_bar(INTEGER_VALUE(n));
    //Is bar protected from garbage collection?
    assert(X->bar);
    PROTECT( ptr_foo = R_MakeExternalPtr(X, install("extptr_foo"), R_NilValue) );
    R_RegisterCFinalizerEx( ptr_foo, ptr_foo_finalize, 1 );
    UNPROTECT( 1 );
    return (ptr_foo);
} 

Thanks,

RT


It looks like your foo object is your own creation (not and SEXP). If so, it has nothing to do with R and is NOT garbage collected and therefore does not need to be/can't be protected. No one will look at it or its fields but you.

The bar object you put in it is also your own creation and not an R object (an SEXP) I assume. If it IS an SEXP or points to data within an SEXP then that data needs to be protected. A safer/easier way would then be to make a copy of the data in the SEXP.

When the ptr_foo object is no longer used by R and garbage collected, your ptr_foo_finalize function will be called to remove your foo object (and the bar part).


For starters, you are not supposed to use calloc() or malloc() for R objects, the "Writing R Extensions" manual is pretty clear on that.

Second, each allocation would get its own PROTECT all.

Third, external pointer objects are R representations of something created elsewhere (for a canonical example , see the RODBC package and its implementation of DB interface). I don't think you're supposed to create external pointer objects from within.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜