R调用的C代码不断崩溃

Posted

技术标签:

【中文标题】R调用的C代码不断崩溃【英文标题】:C code called by R keeps crashing 【发布时间】:2013-04-30 22:55:33 【问题描述】:

以下是我编写的 C 代码的一部分。函数foo 将在R 中调用。代码不断导致R 崩溃,我将问题缩小到这个outer() 函数,它用于计算外和或差。注意被注释掉的部分:如果我不注释掉它,如果每个数组包含超过 1000 个数据点,函数将导致 R 崩溃。如果我将其注释掉,我可以毫无问题地计算明显更长的数组的外部和/差(例如,每个数组超过 100000 个数据点)。我想知道问题是什么...谢谢!

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


//编译代码后,我在R中使用下面的代码来调用函数:

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

【问题讨论】:

这让 R 崩溃了,Rprintf 被注释掉了。 呃。这真的很奇怪。我试了很多次,当Rprintf被注释掉时,它并没有使R崩溃。让我再试一次.. 刚刚又试了一次。它没有问题。真的很奇怪。 @MatthewLundberg:当 R 崩溃时,你的数组大小是多少? 10000,如您的示例。 【参考方案1】:

我认为它超出了堆栈并造成了麻烦。

试试这个:

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

【讨论】:

你是只添加了这些行,还是添加了对malloc的调用? 你能解释一下double* outer_temp_x=malloc(sizeof(double)*(*nsamp)*(*nsamp))double* outer_temp_y=malloc(sizeof(double)*(*nsamp)*(*nsamp))吗?您的代码有效。谢谢!! Writing R Extensions 指向使用R_alloc 进行动态内存分配(返回到R 时自动检索,无需free)和Calloc / Free 用于跨平台的一致性. 谢谢你,@MartinMorgan。在这里,这些没有被退回(这些显然是临时的)所以这不是问题。

以上是关于R调用的C代码不断崩溃的主要内容,如果未能解决你的问题,请参考以下文章

调用 Fortran 例程的 C MPI 程序崩溃

来自dispatch_async全局崩溃的C函数调用,但在主队列上工作

解析facebook登录崩溃目标c

协程不断崩溃而不显示错误

calloc 调用失败,代码崩溃

text 如何使用`.C`接口从R调用Nim代码