-
Debugging help :(
I just want to create a simple code of a moving ball colldiing to each other. I am able to print the results, however, my fprintf isn't working :(. I am quite new to this, so please help? Thank you in advance.
After running it just says "EASY.exe has stopped working..."
My compiler didnt show where the error either.
Code:
#include <stdio.h>
#include <math.h>
#include <conio.h>
typedef double real;
typedef struct
{
real xpos;
real ypos;
real zpos;
real uvel;
real vvel;
real wvel;
real omegax;
real omegay;
real omegaz;
real radius;
real mass;
} sphere;
void update_position(sphere *ball, real dt)
{
//(*ball).xpos
ball->xpos=ball->xpos + dt*ball->vvel;
//ypos,zpos
}
void detect_ball(sphere *ball1, sphere *ball2, real *pdist)
{
*pdist=sqrt((ball2->xpos-ball1->xpos)*(ball2->xpos-ball1->xpos)+
(ball2->ypos-ball1->ypos)*(ball2->ypos-ball1->ypos));
// if ( dist<= (ball1->radius + ball2->radius) +0.0075 )
// {
// if ( dist>= ball1->radius + ball2->radius -0.0075 )
// {
// *ptime=0;
// }
// }
}
int main(int argc, char *argv)
{
real dt=0.01;
real t, dist1, tmax=1, mlimit, firstvvel, gap=1.5, dist[2], ballmatxpos[101][2];
int nballs=1 ;
int i,j,m,k;
sphere *ball;
ball=(sphere *)malloc(nballs*sizeof(sphere));
mlimit=tmax/dt;
//initialise positions
for(i=0;i<=nballs;i++)
{
ball[i].radius=0.5;
ball[i].xpos=(real) i * (2*ball[i].radius + gap);
ball[i].ypos=0.0;
ball[i].uvel=1.0;
ball[0].vvel=1.0;
ball[1].vvel=0.0;
}
//pendulum to be released
// ball[0].xpos=0;
//ball[0].ypos=0;
// firstvvel=0;
//timestep loop
t=0.0;
dist1=0.0;
while(t<tmax)
{
for(m=0;m<=mlimit;m++)
{
//update position
for(i=0;i<=nballs;i++)
{
update_position(&(ball[i]), dt);
}
//collision detection
for(i=0;i<=nballs;i++)
{
for(j=0;j<=nballs;j++)
{
detect_ball(&(ball[i]),&(ball[j]), &dist1);
if ( dist1 <= (ball[i].radius + ball[j].radius) +0.075 )
{
if ( dist1 >= (ball[i].radius + ball[j].radius) -0.075 )
{
// ball2->uvel=ball1->vvel;
//yes collision, modify velocities and rotation rates
t=0;
}
}
}
}
ballmatxpos[m][0]=t;
ballmatxpos[m][1]=ball[0].xpos;
printf("In this case, initial velocity= %3.4lf with t=%3.4lf \n", ballmatxpos[m][0], t );
t+=dt;
}
}
// ---------------//-------------------------
FILE *pFile1;
FILE *pFile2;
pFile1 = fopen("graphing3.txt", "w");
pFile2 = fopen("graphing4.txt", "w");
if (pFile1 != NULL)
{
for(m=0;m<=mlimit;m++)
{
fprintf( pFile1, " %3.4lf \n ", ballmatxpos[m][0]);
}
fprintf( pFile1,"\n");
fclose(pFile1);
}
if (pFile2 != NULL)
{
for(m=0;m<=mlimit;m++)
{
fprintf( pFile2, " %3.4lf \n", ballmatxpos[m][1]);
}
fprintf( pFile2,"\n");
fclose(pFile2);
}
else
{
printf("inda dapat print bro");
}
// -----------------------------------------------------
getch();
return 0;
}
-
Any idea where did i go wrong?
-
Are the files created at all?
-
Yeah. both .but a blank .txt is created,
-
I not you have two variable called dt one global and one local to main, not sure if that's a problem.
If put some printf statement in the file writing routine and write some unformatted text to the file to keep it simple.
-
The formatting of this code makes it difficult to read, which is why you might not be getting more advice. Work on consistent indentation.
Code:
int nballs=1;
// ...
sphere *ball;
// ...
ball=(sphere *)malloc(nballs*sizeof(sphere));
Why are you casting "malloc()"?
FAQ > Casting malloc - Cprogramming.com
"nballs" is equal to one, so you're only allocating enough memory for one instance of "sphere." However, your loops seem to go for over a hundred iterations.
I also don't see where you're freeing the memory you allocate for "ball."
-
I think it should be char **argv perhaps?
Code:
int main(int argc, char **argv);
int main(int argc, char *argv[]);
dunno if that makes a difference.
I always make my files global but the I'm a bad boy :)
-
You declared ball as having room for `nballs' elements but then you index like this
Code:
for (i = 0; i <= nballs; i++) {
ball[i] = ...
ball has indices 0...nballs-1, so this will go outside of the array bounds
-
Announcements - C Programming
Check out rule #3, please don't bump your threads in the future, it's not good forum etiquette. Many of us are quite busy with our own jobs, and volunteer our time to help. A little patience is expected on your part. Furthermore, you would be much more likely to get help if your code didn't look like crap (lack of formatting) and you had a more detailed problem description. Please properly indent and format your code when you post here in the future, so we actually want to read it and help you. A more complete problem description would also help.
No compiler errors/warnings does not mean "it should work", it just means you got the syntax right and didn't do anything too obviously wrong. If you didn't get any compiler warnings, turn up the warning level. Here's what I got:
Code:
$ make ballgcc -Wall -Wunreachable-code -ggdb3 -lm -lpthread ball.c -o ball
ball.c:47: warning: second argument of ‘main’ should be ‘char **’
ball.c: In function ‘main’:
ball.c:55: warning: implicit declaration of function ‘malloc’
ball.c:55: warning: incompatible implicit declaration of built-in function ‘malloc’
ball.c:52: warning: unused variable ‘k’
ball.c:50: warning: unused variable ‘dist’
ball.c:50: warning: unused variable ‘firstvvel’
I'm not too worried about the unused variables (though it's a good idea to clean them up). More importantly, fix argv to be char **argv (note, 2 stars). Also, you need to #include <stdlib.h> if you want to use malloc.
Other problems I saw
- Don't use conio.h. It's outdated and non-standard. You aren't even using any of it's features (except getch, see next item).
- getch is non-standard. Change it to getchar(), which is standard.
- Don't typedef double to real. All it does is confuse people and leave open the possibility for error, since you may change it to a float or long double, and forget to update printf/scanf statements or other stuff. typedef should be used to reduce complex type declarations to something more legible.
- Don't cast the return value of malloc, read this link.
- Check the return value of malloc to make sure you successfully allocated memory, i.e. check if (ball == NULL), and if so, print an error and exit.
- There's a better way to use sizeof with malloc, see below.
- Pay attention to your loops and array bounds. You're going one too far in your for loop on line 66. See below for a better example of dealing with for loops and arrays.
- Don't use magic numbers like 101 or 2. #define some constants, and give them sensible names.
In C, array indexes start at 0, so if you have an array (or malloc'ed "array") of N elements, valid indexes are array[0] to array[N-1]. Thus, the classic for loop is
Code:
int array[N];
// or
int *array;
array = malloc(N * sizeof(*array));
for (i = 0; i < N; i++)
array[i] = i; // i will always be a valid index
Note, I just use <, not <=. Also, notice the sizeof in my malloc call. It's better to use the name of the variable being assigned to, with a * in front. That makes it sizeof(object being pointed to), so that if you ever change the type of array, you only change the declaration, you don't have to track down all the malloc calls and change the sizeof part as well.
One more thing, you run the risk of having another overflow if you change dt or tmax. You declare ballmatxpos to have exactly 101 elements, but with different dt and tmax values, mlimit may be larger than that, so your loop will go too far. Try using a variable length array (declare it after you calculate mlimit:
Code:
mlimit = tmax / dt;
int ballmatxpos_entries = (int) mlimit + 1;
double ballmatxpos[ballmatxpos_entries][2];
for (m = 0; m < ballmatxpos_entries; m++)
ballmatxpos[m][0] = ...;
Once again, that will prevent any overflows.
EDIT: Note, the array overflow in your loop was causing you to trample on some internal data used by malloc/free (which is also used in fopen/fclose), so you were destroying the file descriptors pFile1 and/or pFile2, thus the fprintf wasn't working. Fixing the loop should fix that error too.
-
I think ball might need for be a sphere **?
Not sure of thus as only briefly looked, but you you have a pointer to a ball and an array of such pointers???
So I am not sure if ball[i] makes any sense as it is declared.
-
You see ball is a pointer to a sphere, I think you need a pointer to a pointer to a sphere.
If you just have pointer to sphere I don't think ball[0] makes much sense, certainly as you have only allocated one sphere, certainly ball[1] would not make much sense?
IT woudl be like
char *fred
then saying fred[0]=&'s', that's not good, fred=&'s' is OK though??
Or is it *fred='s' and *fred[1]='s'.
-
Code:
sphere **ball;
mlimit=tmax/dt;
//initialise positions
for(i=0;i<=nballs;i++)
{
ball[i]=(sphere *)malloc(nballs*sizeof(sphere));
ball[i].radius=0.5;
ball[i].xpo
I think the above is better.
-
Or for 10(?) balls
Code:
sphere *ball[10];
mlimit=tmax/dt;
//initialise positions
for(i=0;i<=nballs;i++)
{
ball[i]=(sphere *)malloc(nballs*sizeof(sphere));
ball[i].radius=0.5;
ball[i].xpo
-
So if you change that hopefully your program will be a load of balls :D :p
-
@esbo: The declaration of balls is correct. The OP is malloc'ing an array of spheres (not an array of pointers to sphere), so the variable should be declared sphere *balls; as he has it. sphere **balls would be for a 2-d "array" of spheres, or if he wanted to malloc each sphere in the array. I'm not sure what you were getting at with your &'s' example, but that's not valid C. Read up a bit on some array and dynamic memory tutorials for C, hopefully that will clear things up for you.