2013-05-07 20 views
6

Dưới đây là một phần của mã C tôi đã viết. Hàm foo sẽ được gọi bằng R. Mã giữ nguyên R bị lỗi và tôi đã thu hẹp sự cố xuống hàm outer() này, được sử dụng để tính toán tổng hoặc khác biệt bên ngoài. Lưu ý phần được nhận xét ra: Nếu tôi không bình luận nó ra, chức năng sẽ dẫn R sụp đổ nếu mỗi mảng có chứa, nói rằng, hơn 1000 điểm dữ liệu. Nếu tôi nhận xét nó ra, tôi có thể tính toán tổng hợp/chênh lệch bên ngoài cho các mảng dài hơn đáng kể mà không có vấn đề gì (ví dụ: trên 100000 điểm dữ liệu cho mỗi mảng). Tôi tự hỏi vấn đề là gì ... Cảm ơn bạn!Mã C được gọi bằng R giữ lỗi

#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]); 

} 

// Sau khi biên dịch mã, tôi sử dụng mã dưới đây vào R để gọi hàm:

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

này bị treo R đối với tôi, với 'Rprintf' nhận xét ra. –

+0

Uh. Thật kỳ quặc. Tôi đã thử nó nhiều lần, và nó đã không sụp đổ R khi Rprintf được nhận xét. Để tôi thử lại lần nữa .. – Alex

+0

Chỉ cần thử lại lần nữa. Nó hoạt động không có vấn đề gì. Thật kỳ lạ. – Alex

Trả lời

7

Tôi nghĩ rằng đó là overunning stack và gây rắc rối.

Hãy thử điều này:

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

Thêm 'free (outer_temp_x)' và 'free (outer_temp_y)' bị đứt R .. – Alex

+0

Bạn chỉ thêm những dòng đó, hoặc cũng thêm các cuộc gọi vào 'malloc'? –

+0

Rất tiếc, lỗi của tôi! Tôi không nhận thấy những thay đổi khác. Bị phân tâm trong một giây .. – Alex

Các vấn đề liên quan