I am trying to create an mpi program that will run my bellard function to calculate pi to ten thousand decimal places. When i run the program i am presented with the following errors, I have done some searching online and on the openMpi website, the problem appears to be a null pointer but i have looked through the code and cant seem to find it.
The error is:
Signal :segmentation fault(11)
Signal :address not mapped(1)
Failing at address : (nil)
Can anyone see the null pointer ?
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mpi/mpi.h>
#define PRECISION 10000
float minus_one,one,two,three,four,five,six,seven,eight,nine,ten,
thirty_two,sixty_four,two_five_six,one_zero_two_four,
two_pow_six,recip_two_pow_six;
float *pi;
int rank,size;
void init(){
printf("\nstarted init function");
minus_one = -1.0;
one = 1.0;
two = 2.0;
three = 3.0;
four = 4.0;
five = 5.0;
six = 6.0;
seven = 7.0;
eight = 8.0;
nine = 9.0;
ten = 10.0;
thirty_two = 32.0;
sixty_four = 64.0;
two_five_six = 256.0;
one_zero_two_four = 1024.0;
two_pow_six = pow(two,6);
recip_two_pow_six = one/two_pow_six;
pi = 0;
printf("\nended init function");
return;
}
float *bellard(int start, int end,int rank){
float *terms;
float t,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,
t13,t14,t15,t16,t17,tx,ty,tz;
int offset = rank;
double start_k = start;
double end_k = end;
start_k = offset * (PRECISION /size);
end_k = (offset+1) * (PRECISION/size);
terms=0;
int k = start_k;
while( (k<PRECISION) && (k<end_k)){
t1 = k;
t2 = t1*ten;
t3 = t2+one;
t4 = two_five_six/t3;
t5 = t2+nine;
t6 = one/t5;
t7 = t2+three;
t8 = sixty_four/t7;
t9 = four*t1;
t10 = t9+one;
t11 = thirty_two/t10;
t12 = t2+five;
t13 = four/t12;
t14 = t2+seven;
t15 = four/t14;
t16 = t9+three;
t17 = one+t16;
t = t4+t6;
t = t-t8;
t = t-t11;
t = t-t13;
t = t-t15;
t = t-t17;
tx = pow(minus_one,k);
ty = pow(one_zero_two_four,k);
tz = tx/ty;
*terms = tz*t;
//pi = pi+terms;
k = k+1;
}
return terms;
}
int main(int argc, char** argv){
int i;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int elementsCount = 10000/(size-1);
float *workerPi;
float *tmpPi=0;
init(); //initialise variables
printf("\nim here 1");
if(rank == 0)
{
for(i=1; i < size; i++){
printf("\nin recv loop");
MPI_Recv(tmpPi,PRECISION,MPI_FLOAT,i,1,MPI_COMM_WORLD,&status);
*pi=*pi+*tmpPi;
}
}else{
//int i;
int start,end,slice,workers;
workerPi = malloc(sizeof(int)*elementsCount);
workers = size-1;
slice = 10000/workers;
start = (rank-1)*slice;
end = start+slice;
printf("\nWorker %d processing data %d to %d\n",rank,start,end);
workerPi = bellard(start,end,rank);
printf("\nworker finished pi");
MPI_Send(workerPi,slice,MPI_FLOAT,0,1,MPI_COMM_WORLD);
printf("\nworker sent stuff");
}
MPI_Finalize();
return 0;
}
In the bellard function, terms is declared as a pointer to float
float *terms;
and initialized to zero (aka null) a few lines down
terms=0;
Towards the end of the while loop, it is dereferenced:
*terms = tz*t;
The statement *terms is a null pointer dereference and will crash. It is essentially asking to store the result of tz*t into memory address zero, which is not a valid memory address.
The fix may be to declare and use terms as a float, not a pointer to a float (float*).
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have written a code for a simple pendulum with numerical integration using rk4 method. Here's an image of expected result.
It works on my laptop, running Ubuntu 14.04, 64 bit, (it gives a sine wave as the result), but doesn't work on my PC, which runs Debian 8 and is also 64 bit.
Here's an image of the wrong plot.
Any reason why this would be happening?
Here's the code:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
int N = 2;
float h = 0.001;
struct t_y_couple {
float t;
float *y;
};
struct t_y_couple integrator_rk4(float dt, float t, float *p1);
void oscnetwork_opt(float t, float *y, float *dydt);
int main(void) {
/* initializations*/
struct t_y_couple t_y;
int i, iter, j;
// time span for which to run simulation
int tspan = 20;
// total number of time iterations = tspan*step_size
int tot_time = (int)ceil(tspan / h);
// Time array
float T[tot_time];
// pointer definitions
float *p, *q;
// vector to hold values for each differential variable for all time
// iterations
float Y[tot_time][2];
// N = total number of coupled differential equations to solve
// initial conditions vector for time = 0
Y[0][0] = 0;
Y[0][1] = 3.14;
// set the time array
T[0] = 0;
// This loop calls the RK4 code
for (i = 0; i < tot_time - 1; i++) {
p = &Y[i][0]; // current time
q = &Y[i + 1][0]; // next time step
// printf("\n\n");
// for (j=0;j<N;j++)
// call the RK4 integrator with current time value, and current
// values of voltage
t_y = integrator_rk4(h, T[i], p);
// Return the time output of integrator into the next iteration of time
T[i + 1] = t_y.t;
// copy the output of the integrator into the next iteration of voltage
q = memcpy(q, t_y.y, (2) * sizeof(float));
printf("%f ", T[i + 1]);
for (iter = 0; iter < N; iter++)
printf("%f ", *(p + iter));
printf("\n");
}
return 0;
}
struct t_y_couple integrator_rk4(float dt, float t, float y[2]) {
// initialize all the pointers
float y1[2], y2[2], y3[2], yout[2];
float tout, dt_half;
float k1[2], k2[2], k3[2], k4[2];
// initialize iterator
int i;
struct t_y_couple ty1;
tout = t + dt;
dt_half = 0.5 * dt;
float addition[2];
// return the differential array into k1
oscnetwork_opt(t, y, k1);
// multiply the array k1 by dt_half
for (i = 0; i < 2; i++)
y1[i] = y[i] + (k1[i]) * dt_half;
// add k1 to each element of the array y
// do the same thing 3 times
oscnetwork_opt(t + dt_half, y1, k2);
for (i = 0; i < 2; i++)
y2[i] = y[i] + (k2[i]) * dt_half;
oscnetwork_opt(t + dt_half, y2, k3);
for (i = 0; i < 2; i++)
y3[i] = y[i] + (k3[i]) * dt_half;
oscnetwork_opt(tout, y3, k4);
// Make the final additions with k1,k2,k3 and k4 according to the RK4 code
for (i = 0; i < 2; i++) {
addition[i] = ((k1[i]) + (k2[i]) * 2 + (k3[i]) * 2 + (k4[i])) * dt / 6;
}
// add this to the original array
for (i = 0; i < 2; i++)
yout[i] = y[i] + addition[i];
// return a struct with the current time and the updated voltage array
ty1.t = tout;
ty1.y = yout;
return ty1;
}
// function to return the vector with coupled differential variables for each
// time iteration
void oscnetwork_opt(float t, float y[2], float *dydt) {
int i;
dydt[0] = y[1];
dydt[1] = -(1) * sin(y[0]);
}
You have a problem of lifetime with your variable yout in integrator_rk4(). You assign address of yout to ty1.y but you use it outside this function. This is undefined behavior.
quick fix:
struct t_y_couple {
float t;
float y[2];
};
struct t_y_couple integrator_rk4(float dt, float t, float y[2]) {
float y1[2], y2[2], y3[2], yout[2];
// ...
ty1.t = tout;
ty1.y[0] = yout[0];
ty1.y[1] = yout[1];
return ty1;
}
You have a lot of useless allocation and you made "spaghetti code" with your global variable. You should not cast the return of malloc.
First we are reading from the files and forming arrays, then we are calculating hanning window(hanning fn) for each array sample , finally we are multiplying(mul fn) the array and the hanning window to form the array final.
#include <stdio.h>
#include<math.h>
#include <stdlib.h>
#include </usr/local/src/libsndfile-1.0.25/libsndfile-1.0.25/src/sndfile.h>
#include </usr/local/src/libsndfile-1.0.25/libsndfile- 1.0.25/src/sndfile.h.in>
void hanning(int);
float w[256];
float mul(float*,int*,float*,float*,int);
int main()
{
SNDFILE *sf1,*sf2,*sf3,*sf4,*sf5,*sout;
SF_INFO info1,info2,info3,info4,info5,infout;
int num_channels;
int num_items1,num_items2,num_items3,num_items4,num_items5;
int num1,num2,num3,num4,num5;
int *buf1,*buf2,*buf3,*buf4,*buf5;
int f1,f2,f3,f4,f5;
int sr1,sr2,sr3,sr4,sr5;
int c1,c2,c3,c4,c5,d;
int i,j=0,N=128,k=0;
float t[128],w1[64],w2[64];
// FILE *out;
hanning(N);
/* Open the WAV file. */
info1.format = 0;
info2.format=0;
info3.format=0;
info3.format=0;
info4.format=0;
info5.format=0;
sf1 = sf_open("/mnt/usb2/voice/a.wav",SFM_READ,&info1);
sf2 = sf_open("/mnt/usb2/voice/na1.wav",SFM_READ,&info2);
sf3 = sf_open("/mnt/usb2/voice/ma.wav",SFM_READ,&info3);
sf4 = sf_open("/mnt/usb2/voice/ra__.wav",SFM_READ,&info4);
sf5 = sf_open("/mnt/usb2/voice/ttha.wav",SFM_READ,&info5);
if (sf1 == NULL)
{
printf("Failed to open the file.\n");
exit(-1);
}
/* Print some of the info, and figure out how much data to read. */
c1 = info1.channels;
c2 = info2.channels;
c3 = info3.channels;
c4 = info4.channels;
c5 = info5.channels;
f1 = info1.frames;
f2 = info2.frames;
f3 = info3.frames;
f4 = info4.frames;
f5 = info5.frames;
sr1 = info2.samplerate;
sr2 = info2.samplerate;
sr3 = info3.samplerate;
sr4 = info4.samplerate;
sr5 = info5.samplerate;
// printf("frames=%d\n",f);
// printf("samplerate=%d\n",sr);
//printf("channels=%d\n",c);
num_items1 = f1*c1;
num_items2 = f2*c2;
num_items3 = f3*c3;
num_items4 = f4*c4;
num_items5 = f5*c5;
//printf("num_items=%d\n",num_items);
/* Allocate space for the data to be read, then read it. */
buf1 = (int *) malloc(num_items1*sizeof(int));
buf2 = (int *) malloc(num_items2*sizeof(int));
buf3 = (int *) malloc(num_items3*sizeof(int));
buf4 = (int *) malloc(num_items4*sizeof(int));
buf5 = (int *) malloc(num_items5*sizeof(int));
num1 = sf_read_int(sf1,buf1,num_items1);
num2 = sf_read_int(sf2,buf2,num_items2);
num3 = sf_read_int(sf3,buf3,num_items3);
num4 = sf_read_int(sf4,buf4,num_items4);
num5 = sf_read_int(sf5,buf5,num_items5);
for(i=0;i<128;i++)
{
if(i<64){
w1[j]=t[i];
j++;}
else{
w2[k]=t[i];
k++;}
}
x1 = (float *) malloc(num_items1*sizeof(float));
x2 = (float *) malloc(num_items2*sizeof(float));
x3 = (float *) malloc(num_items3*sizeof(float));
x4 = (float *) malloc(num_items4*sizeof(float));
x5 = (float *) malloc(num_items5*sizeof(float));
mul(x1,buf1,w1,w2,num_items1);
mul(x2,buf2,w1,w2,num_items2);
mul(x3,buf3,w1,w2,num_items3);
mul(x4,buf4,w1,w2,num_items4);
mul(x5,buf5,w1,w2,num_items5);
//printf("num=%d\n",num);
sf_close(sf1);
sf_close(sf2);
sf_close(sf3);
sf_close(sf4);
sf_close(sf5);
d=num_items1+num_items2+num_items3+num_items4+num_items5;
final = (float *) malloc(d*sizeof(float));
for(j=0;j<num_items1;j++){
final[i]=x1[j];
i++;}
for(j=0;j<num_items1;j++){
final[i]=x1[j];
i++;}
for(j=0;j<num_items1;j++){
final[i]=x1[j];
i++;}
for(j=0;j<num_items3;j++){
final[i]=x3[j];
i++;}
for(j=0;j<num_items4;j++){
final[i]=x4[j];
i++;}
for(j=0;j<num_items1;i++){
final[i]=x1[j];
i++;}
for(j=0;j<num_items5;j++){
final[i]=x5[j];
i++;}
//sout=sf_open(final,SFM_READ,&infout);
// printf("Read %d items\n",num);
/* Write the data to filedata.out. */
/* out = fopen("filedata.txt","w");
if(out==NULL)
{ printf("Error!");
exit(1); }
printf("a");
for (i = 0; i < 100; i++)
{
fprintf(out,"%d ",final[i]);
fprintf(out,"/n");
}
fclose(out);*/
return 0;
}
void hanning(int N)
{
int half, i, idx, n,j=0,k=0;
float PI=3.1428;
// w = (float*) calloc(N, sizeof(float));
// memset(w, 0, N*sizeof(float));
n = N;
if(n%2==0)
{
half = n/2;
for(i=0; i<half; i++)//Calculates Hanning window samples.
{w[i] = 0.5 * (1 - cos(2*PI*(i+1) / (n+1)));
printf("%f\n",w[i]);}
idx = half-1;
for(i=half; i<n; i++) {
w[i] = w[idx];
printf("%f\n",w[i]);
idx--;
}
}
else
{
half = (n+1)/2;
for(i=0; i<half; i++) //Calculates Hanning window for samples
w[i] = 0.5 * (1 - cos(2*PI*(i+1) / (n+1)));
printf("%f\n",w[i]);
}
}
float mul(float *x,int *buf,float *w1,float *w2,int k)/*multiplication of hanning window and array*/
{
float final_1[k],final_2[k];
int i;
for(i=0;i<k;i++){
if(i<64)
final_1[i]=w1[i];
else
final_1[i]=1;}
for(i=0;i<k;i++){
if(i<k-64)
final_2[i]=1;
else
final_2[i]=w2[i];
}
for(i=0;i<k;i++){
x[i]=final_1[i]*final_2[i]*buf[i];
printf("%f\n",x[i]);
}
}
You should initialize your loop variables closer to the actual loops:
There is a missing i=0; after final = (float *) malloc(d*sizeof(float));
This is definitely a bug, but there are other ones: the size you allocate for the final array is probably too small for the copies you make into it: 4 copies of x1, one copy of x3, x4 and x5, but none of x2 (probably a copy/paste bug here).
Also consider using double instead of float for better accuracy in these computations and use M_PI from <math.h> instead of hard coding a very inaccurate value for pi.
Also try and indent your code more consistently, use K&R style for improved readability.
This question already has answers here:
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 8 years ago.
I want to simulate mass distribution code for 10^10 particle of unit mass.
But this code works only if number of particle is 10^8.
long par = 85000000;
float p[85000000][2];
and this shows error if size goes to 10^9 or 10^10
"Relocation truncated to fit"
that is
long par = 85000000;
float p[85000000][2];
how to find the maximum possible indexing range of float array?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
long double net[4096][4096];
int max = 4000;
long par = 85000000;
float p[85000000][2];
int main(int argc, char *argv[]) {
int i;
for( i = 0; i < par/1000; i++) {
p[i][0]= ((long double)rand()/(long double)(RAND_MAX) * (long double)max);
p[i][1]= ((long double)rand()/(long double)(RAND_MAX) * (long double)max);
}
clock_t begin = clock();
for ( i = 0; i < par/1000; i++) {
double x = p[i][0];
double y = p[i][1];
int left = (int)floor(x);
int right = left + 1;
if ( left >= 4095)
printf("out of bound left is %d/n", left);
int bottom = (int)floor(y);
int top = bottom +1;
double fL = x - left;
double fR = 1 - fL;
double fB = y - bottom;
double fT = 1 - fB;
net[left][bottom] = net[left][bottom] +( fT * fR ) ;
net[right][bottom] = net[right][bottom] +( fT * fL ) ;
net[left][top] = net[left][top] +( fB * fR ) ;
net[right][top] = net[right][top] +( fB * fL ) ;
}
clock_t close = clock();
FILE *f = fopen("file.txt", "a");
if (!f) {
printf("Error opening file!\n");
exit(1);
}
fprintf (f,"Computation time for grid size %d X %d and %ld particle is "
"%4.6lf ,\n",max, max,par,(double)(close-begin) );
fclose(f);
}
You are hitting the stack limit with your allocation, you should use malloc, which does the allocation on the heap (a.k.a. dynamic) memory. Then you can use as much memory, as your OS allows you to.
You can use it with the following syntax:
float p[];
p = malloc(85000000 * sizeof(float));
There is even a Wikipedia article about malloc and the similar functions.
As a side-note: this type of error is the namesake of this very site :)
I'm currently working on some code and, up to now, everything has compiled fine. The aim of the code is this:
read input from data file and assign values to an array.
"smooth the data" by taking average of the data on a given interval and replacing each value in that interval with the average.
It's the second part that causing me trouble. In the external function, for some reason it works when my 'for' loop looks like this:
for(i=t; i<t+z; i++)
But I don't want it to do that. I want it to do this:
for(i=t*z; i<(t+1)*z; i++)
When I try to compile, it just crashes out on me. Anyone know the reason why? It's been puzzling me for hours now. All the code is shown below by the way:
#include <stdio.h>
#include <stdlib.h>
float foo(float*, int, int);
int main(int argc, char* argv[])
{
FILE *input;
const char datafile[]="datainput.dat";
input=fopen(datafile, "r");
int i;
int N=0, t=0;
int z=100;
int M=10;
float *a, avg;
a=(float*)malloc(M*sizeof(float));
if((input!=(FILE*) NULL))
{
while(fscanf(input, "%e", &a[t++])==1)
{
if (t>=M)
{
M*=2;
a=(float *)realloc(a, M*sizeof(float));
}
N++;
}
float u[N];
for(t=0; t<N; t++)
{
avg = foo(a, z, t);
u[t] = avg;
}
fclose(input);
}
else
printf("Input file could not be opened.\n");
return(0);
}
float foo(float b[], int z, int t)
{
int i;
int k=0;
float avg;
float sum=0;
for(i=t*z; i<(t+1)*z; i++)
{
sum+=b[i];
k++;
}
avg = sum/(float)k;
return(avg);
}
side note: you'll probably notice the poor practise of defining float u[N] half way down the code. I don't really like this being there, but you'll note that N is a variable that counts the number of values in the input file (initially unknown) and is initally set to N=0, so I'm not sure how I get around that.
additionally, I asked the question earlier on here but my realloc has no clause if it fails. it's something i'm working on though but at the moment it compiles without it being there.
Also, all the data values are of the form float with seven decimal places and in scientific notation, hence the %e.
Thank you!
EDIT: here are some of the values from the data file. Even though the values on the left look ordered, they are actual values in the file and not there to denote the values on the right.
8.0800000e+00 7.0872796e-01
8.0900000e+00 7.1941101e-01
8.1000000e+00 2.1635408e+00
8.1100000e+00 -5.4200807e-01
8.1200000e+00 1.1046968e+00
8.1300000e+00 1.5833782e+00
8.1400000e+00 6.6122899e-01
8.1500000e+00 1.7922273e+00
8.1600000e+00 1.2446803e+00
8.1700000e+00 3.7869871e-01
8.1800000e+00 1.4793635e+00
8.1900000e+00 1.0508171e+00
8.2000000e+00 9.1012735e-01
8.2100000e+00 6.0967729e-01
8.2200000e+00 1.3834455e+00
8.2300000e+00 -5.2312924e-01
8.2400000e+00 9.2566688e-01
8.2500000e+00 7.8145188e-01
8.2600000e+00 4.1410150e-01
8.2700000e+00 1.9796986e+00
8.2800000e+00 5.9372874e-01
8.2900000e+00 1.8696331e+00
8.3000000e+00 2.3058409e+00
So I've been staring at this for awhile. This is what I came up with. The interval (i'm assuming is 100). for the sake of sanity I've changed it to 5 in the code that follows because your sample posted data is only 46 elements long. I must assume yours is much larger than this.
Some things to note:
foo() no longer relies on some whacky 'where do I compute my average' variables. The caller is responsible for passing the starting location and count of elements to average. This, as you will see, makes that code much simpler. This was fundamentally the heart of the problem to begin with, as your allocation loop was fine (save for not checking your realloc return value). There is no reason to complicate that function to try and compute an average somewhere in the middle of some larger array. Keep it simple. Just have the caller tell the function where to start and how many to average.
Though it wasn't specified, I believe z is your "interval" width. The thing to note in the code below is the interval-count calculation. The number of intervals is simply (N+(z-1))/z, which will result in the number of intervals to process, including the last interval which may only be a partial. From there, we simply walk through the original array, partitioning up in z-sized slices, calculating the average, then rewriting the interval we just averaged with the said-same average. The last interval, again, can be a partial, which requires a little bit of extra care.
I changed the data file to be a command line parameter argv[1]. Made it easier for me to test.
Sure hope this is what you were looking for. Thx for the fun, and don't forget to reset the z value in this code back to 100 if you plan on using it.
#include <stdio.h>
#include <stdlib.h>
float foo(float a[], int count);
int main(int argc, char* argv[])
{
if (argc !=2)
return EXIT_FAILURE;
FILE *input=fopen(argv[1], "r");
if (input != NULL)
{
int z=5,t=0;
int M=10,N=0;
float *a = malloc(M*sizeof(float));
while(fscanf(input, " %e", a + N) ==1 )
{
if (++N>=M)
{
void *tmp = realloc(a, (M*=2)*sizeof(float));
if (tmp != NULL)
{
a = tmp;
}
else
{
perror("Failed to allocate memory.");
exit(EXIT_FAILURE);
}
}
}
// compute number of intervals we will process. the last
// interval may be only a partial.
for (t=0;t<N;t+=z)
{
// how many we're doing in this interval
int count = (z < (N-t) ? z : (N-t)), k=0;
float avg = foo(a+t, count);
printf("Avg[%d] = %e\n", t/z, avg);
// smooth over original array with just-found svg.
for (k=0;k<count; a[t+k++] = avg);
}
fclose(input);
// dump the final array content
for (t=0;t<N;++t)
printf("a[%d] = %e\n", t, a[t]);
// release original array.
free(a);
}
else
{
perror("Input file could not be opened.");
}
return(0);
}
// find the average of the range of floats we're given.
float foo(float a[], int count)
{
float sum = 0;
int i = 0;
for(i=0; i<count; sum += a[i++]);
return (sum)/(float)(count);
}
Output (z=5)
Avg[0] = 5.139628e+00
Avg[1] = 3.791246e+00
Avg[2] = 5.332921e+00
Avg[3] = 3.949121e+00
Avg[4] = 5.420036e+00
Avg[5] = 3.866650e+00
Avg[6] = 5.024508e+00
Avg[7] = 3.941051e+00
Avg[8] = 5.466672e+00
Avg[9] = 2.305841e+00
a[0] = 5.139628e+00
a[1] = 5.139628e+00
a[2] = 5.139628e+00
a[3] = 5.139628e+00
a[4] = 5.139628e+00
a[5] = 3.791246e+00
a[6] = 3.791246e+00
a[7] = 3.791246e+00
a[8] = 3.791246e+00
a[9] = 3.791246e+00
a[10] = 5.332921e+00
a[11] = 5.332921e+00
a[12] = 5.332921e+00
a[13] = 5.332921e+00
a[14] = 5.332921e+00
a[15] = 3.949121e+00
a[16] = 3.949121e+00
a[17] = 3.949121e+00
a[18] = 3.949121e+00
a[19] = 3.949121e+00
a[20] = 5.420036e+00
a[21] = 5.420036e+00
a[22] = 5.420036e+00
a[23] = 5.420036e+00
a[24] = 5.420036e+00
a[25] = 3.866650e+00
a[26] = 3.866650e+00
a[27] = 3.866650e+00
a[28] = 3.866650e+00
a[29] = 3.866650e+00
a[30] = 5.024508e+00
a[31] = 5.024508e+00
a[32] = 5.024508e+00
a[33] = 5.024508e+00
a[34] = 5.024508e+00
a[35] = 3.941051e+00
a[36] = 3.941051e+00
a[37] = 3.941051e+00
a[38] = 3.941051e+00
a[39] = 3.941051e+00
a[40] = 5.466672e+00
a[41] = 5.466672e+00
a[42] = 5.466672e+00
a[43] = 5.466672e+00
a[44] = 5.466672e+00
a[45] = 2.305841e+00
Output (z=10)
Avg[0] = 4.465437e+00
Avg[1] = 4.641021e+00
Avg[2] = 4.643343e+00
Avg[3] = 4.482779e+00
Avg[4] = 4.939867e+00
a[0] = 4.465437e+00
a[1] = 4.465437e+00
a[2] = 4.465437e+00
a[3] = 4.465437e+00
a[4] = 4.465437e+00
a[5] = 4.465437e+00
a[6] = 4.465437e+00
a[7] = 4.465437e+00
a[8] = 4.465437e+00
a[9] = 4.465437e+00
a[10] = 4.641021e+00
a[11] = 4.641021e+00
a[12] = 4.641021e+00
a[13] = 4.641021e+00
a[14] = 4.641021e+00
a[15] = 4.641021e+00
a[16] = 4.641021e+00
a[17] = 4.641021e+00
a[18] = 4.641021e+00
a[19] = 4.641021e+00
a[20] = 4.643343e+00
a[21] = 4.643343e+00
a[22] = 4.643343e+00
a[23] = 4.643343e+00
a[24] = 4.643343e+00
a[25] = 4.643343e+00
a[26] = 4.643343e+00
a[27] = 4.643343e+00
a[28] = 4.643343e+00
a[29] = 4.643343e+00
a[30] = 4.482779e+00
a[31] = 4.482779e+00
a[32] = 4.482779e+00
a[33] = 4.482779e+00
a[34] = 4.482779e+00
a[35] = 4.482779e+00
a[36] = 4.482779e+00
a[37] = 4.482779e+00
a[38] = 4.482779e+00
a[39] = 4.482779e+00
a[40] = 4.939867e+00
a[41] = 4.939867e+00
a[42] = 4.939867e+00
a[43] = 4.939867e+00
a[44] = 4.939867e+00
a[45] = 4.939867e+00
It unlikely that sum+=b[i]; will access the array b between 0 and N-1.
You have allocated 10 block for floats which is passed as array parameter for function. In statement sum+=b[i], here b[i] will not ensure that you are not referring at the index out side the array size, as you have "i" which can go beyond 10 e.g. when z=100 and t=1.
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"]]
}
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.