【发布时间】:2022-01-22 13:44:30
【问题描述】:
我正在尝试一些 .External 示例,但出现此错误:
eras(155)
*** caught segfault ***
address 0x556a1f30e334, cause 'memory not mapped'
Traceback:
1: .External("eratostenes", as.integer(n))
2: eras(155)
C代码如下:
#include <R.h>
#include <Rinternals.h>
SEXP eratostenes (SEXP args)
{
SEXP out, vector, number;
int n, k, j, cuantos;
args = CDR(args);
number = CAR(args);
n = asInteger(number);
int P[n+1];
PROTECT(vector = allocVector(INTSXP, n));
for (k=0; k<n; k++){
P[k] = 0;
INTEGER(vector)[k] = 0;
}
P[k] = 0;
for (int i = 2; i <= n; i++ ){
if ( !P[i] ){
INTEGER(vector)[cuantos] = i;
cuantos++;
}
j = 1;
while ( i*j<=n ){
P[i*j] = 1;
j++;
}
}
PROTECT(out = allocVector(INTSXP, cuantos));
for (int i = 0; i < cuantos; ++i){
INTEGER(out)[i] = INTEGER(vector)[i];
}
UNPROTECT(2);
return out;
}
我现在有冗余代码,但我仍在学习这一点。 在 R 中,我这样调用这个函数:
dyn.load("file.so")
eras <- function(n){
stopifnot(n>0)
return(.External("eratostenes",as.integer(n)))
}
eras(155)
R CMD SHLIB file.c 的输出为:
gcc -std=gnu99 -std=gnu11 -I"/usr/share/R/include" -DNDEBUG -fpic -g -O2 -fdebug-prefix-map=/build/r-base-i2PIHO/r-base-4.1.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c file.c -o file.o
gcc -std=gnu99 -std=gnu11 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o file.so file.o -L/usr/lib/R/lib -lR
我在 ubuntu 20.04 中,这是我的 R 版本:
R version 4.1.2 (2021-11-01) -- "Bird Hippie"
Copyright (C) 2021 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)
我已经尝试过类似的 C 代码,但没有发现问题,因为它编译得很好。任何帮助将不胜感激。
【问题讨论】:
-
cuantos在未初始化时使用。使用前设置int cuantos = 0;。 -
"编译得很好"。如果所有程序只要能编译就可以保证正确运行,那将是一个美好的世界。在 C 语言中尤其如此,您不应该做出这样的假设。
-
我在想这可能与调用 unprotect(2) 的时间有关,我想您在返回
out后可能想要这样做。只是似乎您想保留内存空间,直到它实际上不再需要(因为,可能会出现什么问题?)。但这只是猜测。 -
@kaylum 多么愚蠢的错误T_T...这就是工作到很晚时会发生的事情哈哈...谢谢,cuantos 的初始化是问题,非常感谢