-3

I am constantly facing a fatal error when calling a C function in R and I suspect it may be because of the way I have used "realloc" routine for variable n_k in the gCRSF_gibbs function. Can somebody tell me if the reallocation of memory to n_k is correct or not?

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);}

And this is how it is called in 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}
lmo
  • 37,904
  • 9
  • 56
  • 69
Siamak
  • 25
  • 1
  • 1
  • 7

1 Answers1

-1

You're using realloc wrong. It should be:

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

You always want to use realloc like p = realloc(p, size). Otherwise, if the buffer gets moved by realloc, *n_k will be pointing to a freed pointer.

Brian Malehorn
  • 2,627
  • 14
  • 15
  • 3
    Actually this is wrong. If `realloc` fails it returns `NULL` and now you cannot free the memory and so leak. This has been covered many many times. http://stackoverflow.com/a/9071582/505088 – David Heffernan Jan 06 '16 at 22:40
  • Ok, you don't *always* want to use `p = realloc(p, size)`. But this guy is probably some masters student writing a program he'll run once and never again, he doesn't need the most robust solution. Besides, even if he detects he's out of memory, all he can do is print "oh no!" before exiting. – Brian Malehorn Jan 06 '16 at 23:37
  • 1
    I don't agree. I don't see the point in doing it wrong. Why not get it right? – David Heffernan Jan 07 '16 at 07:17
  • 1
    Furthermore, `*n_k` wasn't allocated by the C code's malloc. It's memory owned by R. It cannot be reallocated. So even when you fix the use of `realloc`, it will still be wrong because you cannot use `realloc` on this block of memory. – David Heffernan Jan 07 '16 at 09:09