Thread: Debugging help :(

  1. #1
    Registered User
    Join Date
    Dec 2012
    Posts
    17

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

  2. #2
    Registered User
    Join Date
    Dec 2012
    Posts
    17
    Any idea where did i go wrong?

  3. #3
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Are the files created at all?

  4. #4
    Registered User
    Join Date
    Dec 2012
    Posts
    17
    Yeah. both .but a blank .txt is created,

  5. #5
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    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.

  6. #6
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    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."

  7. #7
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    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

  8. #8
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    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

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    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

    1. 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).
    2. getch is non-standard. Change it to getchar(), which is standard.
    3. 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.
    4. Don't cast the return value of malloc, read this link.
    5. 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.
    6. There's a better way to use sizeof with malloc, see below.
    7. 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.
    8. 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.

  10. #10
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    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.
    Last edited by esbo; 01-11-2013 at 02:31 PM.

  11. #11
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    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'.
    Last edited by esbo; 01-11-2013 at 03:06 PM.

  12. #12
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    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.

  13. #13
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    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

  14. #14
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    So if you change that hopefully your program will be a load of balls

  15. #15
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    @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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help Debugging (ADT)
    By minidragon in forum C Programming
    Replies: 16
    Last Post: 08-08-2011, 06:39 PM
  2. Debugging Dev C++
    By tuurb046 in forum Tech Board
    Replies: 10
    Last Post: 08-16-2007, 12:51 PM
  3. debugging
    By St0rM-MaN in forum Tech Board
    Replies: 13
    Last Post: 07-06-2007, 02:03 PM
  4. help debugging
    By MB1 in forum C++ Programming
    Replies: 6
    Last Post: 11-03-2005, 01:48 PM
  5. VC++ Debugging
    By neandrake in forum C++ Programming
    Replies: 5
    Last Post: 12-02-2003, 07:31 PM