use*_*410 6 c memory-management r externalinterface
在下面的代码中,类型为foo的对象是通过调用foo_new()创建的,而对象的外部指针则返回给R.后续计算通过传递ptr_foo来执行.最终通过显式调用foo_free(foo*X)释放该对象.所有计算都由libfoo执行.
创建ptr_foo的事实是否意味着foo对象中的所有其他动态分配的字段都会自动受到保护?或者,垃圾收集器可能会扫除诸如"bar"之类的字段吗?
SEXP foo_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);
}
Run Code Online (Sandbox Code Playgroud)
谢谢,
RT
看起来您的 foo 对象是您自己的创建(而不是 SEXP)。如果是这样,它与 R 无关,并且不会被垃圾收集,因此不需要/不能受到保护。除了你之外,没有人会看它或它的领域。
我认为您放入其中的 bar 对象也是您自己创建的,而不是 R 对象(SEXP)。如果它是 SEXP 或指向 SEXP 内的数据,则需要保护该数据。一种更安全/更简单的方法是在 SEXP 中制作数据的副本。
当 R 不再使用 ptr_foo 对象并进行垃圾收集时,将调用 ptr_foo_finalize 函数来删除 foo 对象(以及 bar 部分)。
| 归档时间: |
|
| 查看次数: |
1201 次 |
| 最近记录: |