'segmentation fault' error

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kumar222naveen
    New Member
    • Mar 2012
    • 3

    #1

    'segmentation fault' error

    This is my programme in c for solving differential equations.When i run my programme in terminal in ubuntu it it is displaying the following error 'segmentation fault'.For compling the programme gcc lorenz.c and ./a.out is the code.I think the problem with arrays in my programme but i am not able to find that mistake.I get a Segmentation fault if N=1000000 but not in case of 10000. Could anyone please help me with this.




    /*
    solving lorenz system of differential equations by using runge kutta method

    */

    #include<stdio. h>
    #include<stdlib .h>
    #include<math.h >


    #define Step 0.01
    #define N 1000000

    FILE *fp_out;
    const double sigma = 10;
    double bet;
    const double rho = 28;

    int i,k;

    double fx( double x, double y, double z)
    {
    double xdot;
    xdot = sigma * (y - x) ;
    return xdot;
    }

    double fy( double x, double y, double z)
    {
    double ydot;
    ydot = x*(rho - z) - y;
    return ydot;
    }

    double fz( double x, double y, double z)
    {
    double zdot;
    zdot = y * x - bet * z;
    return zdot;
    }


    /*
    putting random initial conditions

    */
    void initial(double *x, double *y, double *z)
    {
    int i;
    //srand((unsigned int)time(0)); //Seed number for rand()
    x[i] = (rand()/(RAND_MAX + 1.0));
    y[i] = (rand()/(RAND_MAX + 1.0));
    z[i] = (rand()/(RAND_MAX + 1.0));

    }

    void rk4(double *x, double *y, double *z)
    {
    double kx1, kx2, kx3, kx4;
    double ky1, ky2, ky3, ky4;
    double kz1, kz2, kz3, kz4;


    for ( k = 0; k < N; k++ )

    {
    {
    kx1 = Step*fx( x[k], y[k], z[k]);
    ky1 = Step*fy( x[k], y[k], z[k]);
    kz1 = Step*fz( x[k], y[k], z[k]);

    kx2 = Step*fx( x[k] + 0.5*kx1, y[k] + 0.5*ky1, z[k] + 0.5*kz1);
    ky2 = Step*fy( x[k] + 0.5*kx1, y[k] + 0.5*ky1, z[k] + 0.5*kz1);
    kz2 = Step*fz( x[k] + 0.5*kx1, y[k] + 0.5*ky1, z[k] + 0.5*kz1);

    kx3 = Step*fx( x[k] + 0.5*kx2, y[k] + 0.5*ky2, z[k] + 0.5*kz2);
    ky3 = Step*fy( x[k] + 0.5*kx2, y[k] + 0.5*ky2, z[k] + 0.5*kz2);
    kz3 = Step*fz( x[k] + 0.5*kx2, y[k] + 0.5*ky2, z[k] + 0.5*kz2);

    kx4 = Step*fx( x[k] + kx3, y[k] + ky3, z[k] + kz3);
    ky4 = Step*fy( x[k] + kx3, y[k] + ky3, z[k] + kz3);
    kz4 = Step*fz( x[k] + kx3, y[k] + ky3, z[k] + kz3);


    x[k+1] = x[k] + ( kx1 + 2.0*( kx2 + kx3 ) + kx4 )/6.0;
    y[k+1] = y[k] + ( ky1 + 2.0*( ky2 + ky3 ) + ky4 )/6.0;
    z[k+1] = z[k] + ( kz1 + 2.0*( kz2 + kz3 ) + kz4 )/6.0;

    }
    }
    }

    void out_sys( double *x, double *y, double *z)
    {
    for( k = 9000; k < N; k++ )
    {
    fprintf(fp_out, "%lf\t", k*Step);
    fprintf(fp_out, "%lf\t%lf\t%lf\ n", x[k], y[k], z[k]);
    }
    }

    int main()
    {
    double x[N];
    double y[N];
    double z[N];

    char fn_out[50];
    int i;

    /*
    give value of bet
    */
    {
    //initialize

    bet=8/3;

    initial(x,y,z);

    rk4(x,y,z);

    //writing the output file
    sprintf(fn_out, "bh_%.1lf.out", bet);
    fp_out = fopen(fn_out,"w ");
    out_sys(x,y,z);

    fclose(fp_out);

    }
    return 0;
    }
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    It may be right here:

    Code:
    int main()
     { 
    double x[N];
     double y[N];
     double z[N];
     etc...
    N is 1000000 so you have 3 million doubles where each double is probably 8 bytes resulting in 24MB on the stack.

    Often stack memory is limited so you may have exhausted all of your stack memory.

    So the first thing I would do is use malloc() to allocate these arrays on the heap, which is essentially unlimited in size.

    You would not need to change anything else in your code.

    Comment

    • limweizhong
      New Member
      • Dec 2006
      • 62

      #3
      A quick way to solve this is to make your those variables global variables (outside the int main function), which will be on the heap.

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        You can't make that statement. The concept of "stack" and "heap" are not part of the language specification. The only way to know a variable is on the heap is to allocate it yourself. Otherwise, your compiler will allocate it and you have no idea where it is.

        All you can say is that a variable defined outside any block (pair of braces) has the scope from the point od definition to the end of the source file that defines it.

        Comment

        • limweizhong
          New Member
          • Dec 2006
          • 62

          #5
          Ok. Thanks for the correction. I shouldn't say it's heap then. All I can say is that it has space enough for the original poster's 1000000-sized array. (I had always been declaring large arrays as global variables; didn't think anything was wrong with that.)

          Comment

          • kumar222naveen
            New Member
            • Mar 2012
            • 3

            #6
            I have used it but still i am not getting.can you pls correct it in my programme because i am newer to c and i dont know how to use malloc()[where i have to use it] in my programme.

            Comment

            • limweizhong
              New Member
              • Dec 2006
              • 62

              #7
              If you want to do it my way, just transfer these three lines
              Code:
              double x[N];
              double y[N];
              double z[N];
              all the way to the top, after #define N 1000000. Note that although you have local variables x, y and z in the other functions, within those functions, x, y and z will still refer to the local variable (in that scope the global variables x, y and z are "hidden").

              If you want to do it weaknessforcats 's way, don't do the above. Instead delete the three lines mentioned, and in its place put:
              Code:
              double *x,*y,*z;
              x=(double*)malloc(sizeof(double)*N);
              y=(double*)malloc(sizeof(double)*N);
              z=(double*)malloc(sizeof(double)*N);
              Or I might make it:
              Code:
              double *x,*y,*z;
              x=(double*)malloc(sizeof(double)*N*3);
              y=x+N;
              z=y+N;
              just for fun.

              Comment

              • kumar222naveen
                New Member
                • Mar 2012
                • 3

                #8
                thanks yaar but , i tried all methods which are shown above but still i am getting the same error 'segmentation fault'

                Comment

                • weaknessforcats
                  Recognized Expert Expert
                  • Mar 2007
                  • 9214

                  #9
                  Then you are address modifying yourself beyond the array bounds.

                  Like maybe right here:

                  Code:
                  x[k+1] = x[k] + ( kx1 + 2.0*( kx2 + kx3 ) + kx4 )/6.0;
                   y[k+1] = y[k] + ( ky1 + 2.0*( ky2 + ky3 ) + ky4 )/6.0;
                   z[k+1] = z[k] + ( kz1 + 2.0*( kz2 + kz3 ) + kz4 )/6.0;
                  k varies from 0 to <N. Therefore, on the Nth cycle of the loop k<N is true so you go inside the loop and operate on K+1, which is N but there is no Nth element of the array. Remember, for arrays the index varies from 0 to <N.

                  Comment

                  • AlexGr
                    New Member
                    • Feb 2016
                    • 1

                    #10
                    FOUND A SOLUTION !!
                    although nothing from above helped me either when i visited the site for a solution , i came back to post my solution.

                    The error is probably about the memory used . I am not linux or c++ (i started 2 months ago) geek but , you can get rid of the arrays and print your computation in a txt with a very simple #include <ftsream> header

                    it would be somethin like that
                    ...
                    #include <fstream>

                    int main(){

                    ofstream txtvalues;
                    txtvalues.open( "/home/put_your_path_h ere/file_name.txt") ;
                    x0=...;
                    y0=...;
                    z0=....;
                    t0=....;

                    x=x0;
                    y=y0;
                    z=z0;
                    t=t0;
                    for(int i......){
                    ....
                    RUNGE KUTTA HERE
                    ...
                    txtvalues<<t<<" "<<x<<" "<<y<<" "<<z<<"\n";
                    }
                    txtvalues.close ()

                    }

                    And you are done . If you want to visualize your results , u can use gnuplot , it is quite easy.

                    Hope i helped someone

                    Comment

                    Working...