【问题标题】:Calling C in RStudio causes crash在 RStudio 中调用 C 会导致崩溃
【发布时间】:2016-04-11 04:19:39
【问题描述】:

在 R 中调用 C 函数时,我经常遇到致命错误,我怀疑这可能是因为我在 gCRSF_gibbs 函数中对变量 n_k 使用“realloc”例程的方式。谁能告诉我重新分配给 n_k 的内存是否正确?

void gCRSF_gibbs(double *z, double **n_k, double *SampleDex,
             double *r, double *a, double *p,
             int *Ksize, int *WordNum) {

int i, j, k;
double mass;

double *prob_cumsum;
double cum_sum, probrnd;

prob_cumsum = (double *) calloc(Ksize[0],sizeof(double));

mass = r[0]*pow(p[0],-a[0]); 
for (i=0;i<WordNum[0];i++){
    j = (int) SampleDex[i] -1;
    k = (int) z[j] -1;
    if(z[j]>0){
        (*n_k)[k]--;
    }
    for (cum_sum=0, k=0; k<Ksize[0]; k++) {
        cum_sum += (*n_k)[k]-a[0];
        prob_cumsum[k] = cum_sum;
    }

    if ( ((double) rand() / RAND_MAX * (cum_sum + mass) < cum_sum)){
        probrnd = (double)rand()/(double)RAND_MAX*cum_sum;
        k = BinarySearch(probrnd, prob_cumsum, Ksize[0]);
    }
    else{
        for (k=0; k<Ksize[0]; k++){
            if ((int) (*n_k)[k]==0){
                break;
            }
        }
        if (k==Ksize[0]){
            Ksize[0]++;
            realloc(*n_k,sizeof(**n_k)*Ksize[0]);
            (*n_k)[Ksize[0]-1]=0;
            prob_cumsum =  realloc(prob_cumsum,sizeof(*prob_cumsum)*Ksize[0]); 
        }
    }
    z[j] = k+1;
    (*n_k)[k]++;
}
free(prob_cumsum);}

这就是它在 R 中的调用方式:

gCRSF_gibbs <- function(z, n_k, sampleDex, r, a, p){
out <- .C("gCRSF_gibbs", z=as.double(z), n_k=as.double(n_k), 
          SampleDex=as.double(sampleDex), r=as.double(r), a=as.double(a),
          p=as.double(p), Ksize=as.integer(length(n_k)),
          WordNum=as.integer(length(sampleDex)))
out}

【问题讨论】:

  • 我们如何调用这个函数? (包括你的 R 代码。)
  • 我使用过“realloc”例程”:不要。请参阅编写 R 扩展。
  • 如果你愿意使用 C++(这确实对 R 更好),那么 Rcpp 有一堆 Gibbs 采样器示例可以工作
  • 嗨,德克!你能更具体地说明不使用 realloc 吗?您指的是编写 R 扩展的哪一部分?

标签: c r pointers realloc


【解决方案1】:

您使用 realloc 错误。应该是:

*n_k = realloc(*n_k,sizeof(**n_k)*Ksize[0]);

您总是想像p = realloc(p, size) 一样使用realloc。否则,如果缓冲区被realloc 移动,*n_k 将指向一个已释放的指针。

【讨论】:

  • 其实这是错误的。如果realloc 失败,它将返回NULL,现在您无法释放内存并因此泄漏。这已经被报道过很多次了。 stackoverflow.com/a/9071582/505088
  • 好吧,你不会总是想使用p = realloc(p, size)。但是这家伙可能是某个硕士生在编写一个他将运行一次并且永远不会再次运行的程序,他不需要最强大的解决方案。此外,即使他发现自己内存不足,他也只能打印“哦不!”在退出之前。
  • 我不同意。我看不出做错事的意义。为什么不做对呢?
  • 此外,*n_k 不是由 C 代码的 malloc 分配的。它是 R 拥有的内存。它不能被重新分配。所以即使你修复了realloc的使用,它仍然会出错,因为你不能在这块内存上使用realloc
猜你喜欢
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多