I'm writing a program for an assignment I have at school to model the oscillations of a coupled harmonic oscillator (a block connected to a wall by a spring, and another block connected to the first block by a spring). With this my extension I have chosen is to model n blocks connected by n springs! Up to a reasonable amount, I started by trying 3.
When I attempt to compile it it compiles fine and I can run the program for the first part which only requires input. After that it just crashes, giving a bus error. Here is my code, sorry it might seem like a wall!! It begins by taking a number of values from the command like for the positions of the blocks.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
/* Set variables for the width of the blocks and rest length of the springs*/
#define w 1.0
#define R 1.0
/*Define our external function for finding the runge kutta constants*/
double rkutta(double *xpos, double *omeg, double *j, int delta, int n, int N);
int main(int argc, char *argv[])
{
FILE* output;
int tmp, N;
double *x, *v, *m, *k, *omega, mtmp, ktmp, t, dt, *xstep, *vstep;
/*Find value of number of masses from the command line*/
N = argc - 1;
dt = 0.001;
/*Allocate array memory for each variable required*/
x = malloc(N*sizeof(double));
v = malloc(N*sizeof(double));
m = malloc(N*sizeof(double));
k = malloc(N*sizeof(double));
omega = malloc((2*N - 1)*sizeof(double));
/*Read values for the x position of each mass from command line*/
if(x != NULL && v != NULL && m != NULL && k != NULL && omega !=NULL)
{
for(tmp=0; tmp<N; tmp++)
{
sscanf(argv[tmp+1], "%lf", &x[tmp]);
}
}
else
{
printf("***************************\n");
printf("**Error allocating arrays**\n");
printf("***************************\n");
}
/*Check there are an appropriate amount of masses,
if so take values for other quantities from user*/
if(N <= 1)
{
printf("************************************\n");
printf("**There must be at least 2 masses!**\n");
printf("************************************\n");
}
else if(N == 2)
{
for(tmp=0; tmp<N; tmp++)
{
printf("Input a value for the velocity of Block %d\n", tmp+1);
scanf("%lf", &v[tmp]);
}
for(tmp=0; tmp<N; tmp++)
{
printf("Input a value for the mass of Block %d\n", tmp+1);
scanf("%lf", &m[tmp]);
}
for(tmp=0; tmp<N; tmp++)
{
printf("Input a value for the spring constant of Spring %d\n", tmp+1);
scanf("%lf", &k[tmp]);
}
}
else
{
for(tmp=0; tmp<N; tmp++)
{
printf("Input a value for the velocity of Mass %d\n", tmp+1);
scanf("%lf", &v[tmp]);
}
printf("Input a value for the mass of each Block\n");
scanf("%lf", &mtmp);
for(tmp=0; tmp<N; tmp++)
{
m[tmp] = mtmp;
}
printf("Input a value for the spring constant of each Spring\n");
scanf("%lf", &ktmp);
for(tmp=0; tmp<N; tmp++)
{
k[tmp] = ktmp;
}
}
/*Compute values of each omega*/
for(tmp=0; tmp<(2*N-1); tmp++)
{
if(tmp % 2)
{
omega[tmp] = k[(tmp+1)/2] / m[(tmp-1)/2];
}
else
{
omega[tmp] = k[tmp/2] / m[tmp/2];
}
}
/*Define arrays for runge kutta constants*/
double *a, *b, *c, *d;
/*Calculate the values of the runge kutta constants*/
for(tmp=0; tmp<(2*N); tmp++)
{
if(tmp < N)
{
a[tmp] = v[tmp];
}
else
{
a[tmp] = rkutta(x, omega, 0, 0, (tmp-N), N);
}
}
for(tmp=0; tmp<(2*N); tmp++)
{
if(tmp < N)
{
b[tmp] = v[tmp] + 0.5*dt*a[tmp+2];
}
else
{
b[tmp] = rkutta(x, omega, a, (0.5*dt), (tmp-N), N);
}
}
for(tmp=0; tmp<(2*N); tmp++)
{
if(tmp < N)
{
c[tmp] = v[tmp] + 0.5*dt*b[tmp+2];
}
else
{
c[tmp] = rkutta(x, omega, b, (0.5*dt), (tmp-N), N);
}
}
for(tmp=0; tmp<(2*N); tmp++)
{
if(tmp < N)
{
d[tmp] = v[tmp] + dt*c[tmp+2];
}
else
{
d[tmp] = rkutta(x, omega, c, dt, (tmp-N), N);
}
}
/*Open file to output data*/
output = fopen("1209937_proj1.out", "w");
for(t=0; t<=0.1; t=t+dt)
{
if(output != (FILE*)NULL)
{
fprintf(output, "%lf ", t);
for(tmp=0; tmp<N; tmp++)
{
fprintf(output, "%lf ", x[tmp]);
}
for(tmp=0; tmp<N; tmp++)
{
if(tmp<N-1)
{
fprintf(output, "%lf ", v[tmp]);
}
else
{
fprintf(output, "%lf\n", v[tmp]);
}
}
}
else
{
printf("*********************************\n");
printf("**Error outputting data to file**\n");
printf("*********************************\n");
return(EXIT_FAILURE);
}
/*Use runge kutta to find the next value of v and x*/
for(tmp=0; tmp<N; tmp++)
{
xstep[tmp] = x[tmp] + (dt/6)*(a[tmp]+2*b[tmp]+2*c[tmp]+d[tmp]);
vstep[tmp] = v[tmp] + (dt/6)*(a[tmp+2]+2*b[tmp+2]);
vstep[tmp] = vstep[tmp] + (dt/6)*(2*c[tmp+2]+d[tmp+2]);
x[tmp] = xstep[tmp];
v[tmp] = vstep[tmp];
}
}
free(x);
free(v);
free(m);
free(k);
free(omega);
fclose(output);
return(EXIT_SUCCESS);
}
/*Given various quantities find runge kutta values*/
double rkutta(double *xpos, double *omeg, double *j, int delta, int n, int N)
{
int temp;
double result;
result = 0;
for(temp=0; temp<N; temp++)
{
xpos[temp] = xpos[temp] + delta*j[temp];
}
if(n=0)
{
result = -omeg[n]*(xpos[n]-R) + omeg[n+1]*(xpos[n+1]-xpos[n]-w-R);
}
else if(n < N-1)
{
result = -omeg[2*n]*(xpos[n]-xpos[n-1]-w-R);
result = result + omeg[(2*n+1)]*(xpos[n+1]-xpos[n]-w-R);
}
else
{
result = -omeg[(2*n-1)]*(xpos[n]-xpos[n-1]-w-R);
}
return(result);
}
I haven't really done much programming so I'm sorry if it's something obvious. I just want to fix it. The program runs up until after all the data has been put in by the user.
Running in the debugger it fails here for me:
Looking at
a
we find that its un-initialized.Looking at your program, we see that you define:
But you have not defined an array, you've defined an empty pointer and not set it to anything.
Change this to
And then the compiler will create memory for those (at least for N up to 50).