zev.kronenberg
zev.kronenberg

Reputation: 75

caught segfault in [R] function

I am very new to C but know my way around [R]. This error could be a very stupid mistake in C.

My C code does kernel smoothing.

*When I comment out the last line of code my function works: results[i] = v; *

This call kills R:

new.y<-zsmooth2( x=c(0:80000), xpts=dat$V2, ypts=dat$V4, h=10000)

* caught segfault * address 0x1184f8000, cause 'memory not mapped'

Traceback: 1: .C("kernel_smooth", as.double(x), as.double(ypts), as.double(xpts), as.integer(n), as.integer(nxpts), as.double(h), result = double(length(xpts))) 2: zsmooth2(x = c(0:80000), xpts = dat$V2, ypts = dat$V4, h = 10000)

C-code:

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


void kernel_smooth(double *x, double *ypts,  double *xpts, int *n, int *nxpts, double *h, double *results){
    int i, j;

    for(i = 0; i < *n; i++){

        double nsum = 0;
        double dsum = 0;

        double z = x[i] + *h;
        double y = x[i] - *h;

        for(j = 0; j < *nxpts; j++){

            if(xpts[j] < y){
                continue;
            }   
            if(xpts[j] > z){
                break;
            }   
            double d = (xpts[j] - i) / *h;
            double r = dnorm(d, 0, 1, 0);
            nsum += r * ypts[j];
            dsum += r;  
        }   
            Rprintf("test:i %d\n", i);  
            double v = nsum / dsum;
            Rprintf("test:v %f\n", v);  

         results[i] = v;  
    }

}

R-code:

 dyn.load("~/github/ZevRTricks/smoother1.so")
 zsmooth2<-function(x, ypts, xpts, h){
    n <- length(x)
    nxpts <- length(xpts)
    dens  <- .C("kernel_smooth", as.double(x), as.double(ypts), 
                as.double(xpts), as.integer(n), as.integer(nxpts), 
                as.double(h), result = double(length(xpts)))
dens[["result"]]
}

Upvotes: 1

Views: 2551

Answers (1)

Tyler
Tyler

Reputation: 10032

xpts and ypts are vectors, and in your C code you are trying to access elements 1 to n in each of them. n is the length of x, which is 100 times longer in your second example than in your first example. Compare seq(from = 0, to = 80000 by = 100) to 0:80000, (and while you're at it you can drop the c() from around the 0:80000).

So I guess that xpts and ypts are at least 801 elements long, but less than 80001 elements. You've messed up your indexing somewhere.

Note also that you pass x to your C code, but don't actually use it for anything.

Upvotes: 2

Related Questions