2016-01-06 2 views
-3

Я постоянно сталкиваюсь с фатальной ошибкой при вызове функции C в R, и я подозреваю, что это может быть из-за того, как я использовал процедуру «realloc» для переменной n_k в функции gCRSF_gibbs. Может ли кто-нибудь сказать мне, правильно ли перераспределение памяти на n_k или нет?Вызов C в RStudio вызывает сбой

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} 
+0

И как мы называем эту функцию? (Включите свой R-код.) – nrussell

+5

_I использовал «realloc» рутину »_: Не смотрите. См.« Написание расширений R ». –

+4

И если вы открыты для использования C++ (что лучше для R, действительно), то Rcpp имеет связку из примеров сэмплера Gibbs _that work_. –

ответ

-1

Вы используете realloc неправильно. Оно должно быть:

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

Вы всегда хотите использовать realloc как p = realloc(p, size). В противном случае, если буфер перемещается на realloc, *n_k будет указывать на освобожденный указатель.

+3

На самом деле это неправильно. Если 'realloc' failed, он возвращает' NULL' и теперь вы не можете освободить память и, следовательно, течь. Это было рассмотрено много раз. http://stackoverflow.com/a/9071582/505088 –

+0

Хорошо, вы не * всегда * хотите использовать 'p = realloc (p, размер) '. Но этот парень, вероятно, является мастером-учеником, который пишет программу, которую он будет запускать один раз и никогда больше, ему не нужно самое надежное решение. Кроме того, даже если он обнаруживает, что у него не хватает памяти, все, что он может сделать, это напечатайте «oh no!» перед выходом. –

+1

Я не согласен. не вижу смысла делать это неправильно. Почему бы не понять это правильно? –