R VECSXP中的保护元件
在“编写R扩展”手册中,它说R VECSXP中的保护元件,r,R,在“编写R扩展”手册中,它说 Protecting an R object automatically protects all the R objects pointed to in the corresponding SEXPREC, for example all elements of a protected list are automatically protected. 这是否意味着我不需要保护VECSXP的单个SEXP元素。例如,考虑下面包含两种方法,我希望在这里说明我需要澄
Protecting an R object automatically protects all the R objects pointed to in the
corresponding SEXPREC, for example all elements of a protected list are automatically
protected.
这是否意味着我不需要保护VECSXP
的单个SEXP
元素。例如,考虑下面包含两种方法,我希望在这里说明我需要澄清:
#include <Rinternals.h>
#include <R.h>
SEXP copy_int_vec(int *x, int size) {
SEXP ans = allocVector(INTSXP, size);
PROTECT(ans);
int *pans = INTEGER(ans);
for (int i = 0; i < size; i ++) {
pans[i] = x[i];
}
UNPROTECT(1);
return ans;
}
// method 1 - protect VECSXP when allocated BUT NOT individual array entries
SEXP method_one() {
// setup for rep example
int N = 3;
int *graph[N];
int tmp1[3] = {1, 2, 3};
int tmp2[4] = {1, 2, 3, 4};
int tmp3[2] = {3, 4};
graph[0] = tmp1;
graph[1] = tmp2;
graph[2] = tmp3;
int neighbours[3] = {3, 4, 2};
// method
SEXP ans = allocVector(VECSXP, N);
PROTECT(ans);
for (int i = 0; i < N; i++){
SET_VECTOR_ELT(ans, i, copy_int_vec(graph[i], neighbours[i]));
}
UNPROTECT(1);
return ans;
}
// method 2 - protect VECSXP when allocated AND ALSO individual array entries
SEXP method_two() {
// setup for rep example
int N = 3;
int *graph[N];
int tmp1[3] = {1, 2, 3};
int tmp2[4] = {1, 2, 3, 4};
int tmp3[2] = {3, 4};
graph[0] = tmp1;
graph[1] = tmp2;
graph[2] = tmp3;
int neighbours[3] = {3, 4, 2};
// method 2
SEXP ans = allocVector(VECSXP, N);
PROTECT(ans);
for (int i = 0; i < N; i++){
SEXP tmp = copy_int_vec(graph[i], neighbours[i]);
PROTECT(tmp);
SET_VECTOR_ELT(ans, i, tmp);
}
UNPROTECT(N + 1);
return ans;
}
#包括
#包括
SEXP复制(整数*x,整数大小){
SEXP ans=allocVector(INTSXP,大小);
保护(ans);
int*pans=整数(ans);
对于(int i=0;i
我希望答案是第一种方法,但希望能得到澄清。我相信
方法之一
可以
要进行分析,您需要知道代码中执行分配的每一点,因为分配可能会触发垃圾收集,这将释放任何未受保护的对象
因此,通过方法\u one
:
SEXP method_one() {
// setup for rep example
int N = 3;
int *graph[N];
int tmp1[3] = {1, 2, 3};
int tmp2[4] = {1, 2, 3, 4};
int tmp3[2] = {3, 4};
graph[0] = tmp1;
graph[1] = tmp2;
graph[2] = tmp3;
int neighbours[3] = {3, 4, 2};
上面的代码都没有使用R的分配器;这些分配都在C堆栈上,因此它们是安全的
// method
SEXP ans = allocVector(VECSXP, N);
PROTECT(ans);
这将执行R分配,然后立即保护它。写这篇文章更常见的方法是
SEXP ans;
PROTECT(ans = allocVector(VECSXP, N));
这使得在分配和保护之间插入语句更难把事情搞砸
for (int i = 0; i < N; i++){
SET_VECTOR_ELT(ans, i, copy_int_vec(graph[i], neighbours[i]));
}
现在什么都没有得到保护;记住不要在返回之前插入任何代码
return ans;
}
return ans;
}