2013-05-07 9 views
6

Poniżej znajduje się część kodu C, który napisałem. Funkcję foo należy wywołać w R. Kod nadal powoduje awarię R, a ja zawęziłem problem do tej funkcji outer(), która służy do obliczenia zewnętrznej sumy lub różnicy. Zwróć uwagę na tę część, która jest skomentowana: jeśli jej nie skomentuję, funkcja poprowadzi R do awarii , jeśli każda z tablic zawiera, powiedzmy, ponad 1000 punktów danych. Jeśli skomentuję to, mogę obliczyć zewnętrzną sumę/różnicę dla znacznie dłuższych tablic bez problemu (np. Ponad 100000 punktów danych na tablicę). Zastanawiam się, na czym polega problem ... Dziękuję!Kod C wywołany przez R zawiesza się

#include <R.h> 
#include <Rmath.h> 
#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 

void outer(double *x1, double *x2, int *n, int operation, double *output){ 
int i, j; 
if(operation==1){ 
    for(i=0; i<*n; i++){ 
     for(j=0; j<*n; j++){ 
      output[(*n)*i+j]=x1[j]+x2[i]; 
     } 
    } 
} else if(operation==2){ 
    for(i=0; i<*n; i++){ 
     for(j=0; j<*n; j++){ 
      output[(*n)*i+j]=x1[j]-x2[i]; 
      //Rprintf("%d ", (*n)*i+j); //<-----------HERE 
     } 
    } 
} 
} 


void foo(double *x, double *y, int *npred, int *nsamp){ 
int oper=2; 
double xouter[*nsamp], youter[*nsamp]; 
double outer_temp_x[(*nsamp)*(*nsamp)], outer_temp_y[(*nsamp)*(*nsamp)]; 

outer(x, x, nsamp, oper, &outer_temp_x[0]); 
outer(y, y, nsamp, oper, &outer_temp_y[0]); 

} 

// Po kompilacji kodu, używam poniższy kod w R do wywołania funkcji:

dyn.load("foo.so") 
x=as.matrix(rnorm(10000)) 
y=rlnorm(10000) 

invisible(.C("foo", 
      x=as.double(as.vector(x)), 
      y=as.double(y), 
      npred=as.integer(ncol(x)), 
      nsamp=as.integer(length(y)) 
     ) 
+0

to wywala R dla mnie, z 'Rprintf' wykomentowane. –

+0

Uh. To naprawdę dziwne. Próbowałem tego wiele razy, i to nie uległo awarii, gdy Rprintf został skomentowany. Pozwól mi spróbować ponownie. – Alex

+0

Po prostu wypróbowałem to jeszcze raz. Działało bez problemu. Bardzo dziwne. – Alex

Odpowiedz

7

myślę, że to jest overunning stos i powoduje kłopoty.

Spróbuj tego:

void foo(double *x, double *y, int *npred, int *nsamp){ 
    int oper=2; 
    double xouter[*nsamp], youter[*nsamp]; 

    // The prior code allocated on the stack. Here, we make a pair of calls 
    // to 'malloc' to allocate memory for the arrays. This gets memory from 
    // the heap. The stack is fairly limited, but the heap is huge. 
    // 'malloc' returns a pointer to the allocated memory. 

    double* outer_temp_x=malloc(sizeof(double)*(*nsamp)*(*nsamp)); 
    double* outer_temp_y=malloc(sizeof(double)*(*nsamp)*(*nsamp)); 

    outer(x, x, nsamp, oper, &outer_temp_x[0]); 
    outer(y, y, nsamp, oper, &outer_temp_y[0]); 

    // The downside of allocating on the heap, is that you must release the 
    // memory at some point. Otherwise you have what's called a "memory leak." 
    // 'free' is the function to free the memory, and it is called on the 
    // pointer value returned by 'malloc'. 

    free(outer_temp_x); 
    free(outer_temp_y); 
} 
+0

Dodanie 'free (outer_temp_x)' i 'free (outer_temp_y)' spowodowało awarię mojego R .. – Alex

+0

Czy dodałeś tylko te linie, czy też dodałeś połączenia do 'malloc'? –

+0

Ups, moj zły! Nie zauważyłem innych zmian. Został rozproszony na chwilę .. – Alex