简体   繁体   中英

Cause for segmentation fault; pointer value lost after function call

I'm getting a segmentation fault error after the call to function, 'flightdynamics'. The pointer 'impulsevecnorm' seems to 'loose' it's value (ie if I try and access elements it's pointing to, I get a segmentation fault error). If I pass 'impulsevecnorm' to the function, 'flightdynamics', I can print out it's value uptil the return statement but after return, back in main(), it looses it's value. This is odd because in 'flightdynamics' I'm not accessing or changing the value of 'impulsevecnorm' explicitly, so I do not understand why it should 'lose' it's value after. Here's the code:

int main()
{

double *currstate, *nextstate;
  double *impulsevecnorm;

 /* Start a few for loops */
              srand(time(NULL));

          currstate = initialize (vx0, vy0);
          impulsevecnorm = impulsecalc (currstate);
          for (i=0; i<NBALLS; i++)
            {
                double terrain[(int) (NSTEPS*2)] = {0};
                double terrainsl[(int) (NSTEPS*2)] = {0};

                  for (j=0; j<NSTEPS; j++)
                  {

                  printf("%f \n",impulsevecnorm[1]); // At this point it prints fine
                  nextstate = flightdynamics (currstate, terrain, terrainsl, bcounter, tcounter);
                  printf("%f \n",impulsevecnorm[1]); // here i get a segmentation fault and the code stops running
                  ..... 
                  /* to end of function (rest doesn't matter as error appears before this)*/
}}}

double * flightdynamics (double *state, double terrain[], double terrainsl[], double counter, int endterr)
{                                                                                      
    double *out = (double *)malloc ( (NSTATE+3)*sizeof(double) );
    double *hit = (double *)malloc ( 3*sizeof(double) );
    double tx[sizet] = {0}, theight[sizet] = {0};

    for (j = 0; j < sizet; j++)
    {
        tx[j] = ((double) endterr/refine + (double) j)*space;
        theight[j] = randomground();
    }

    gsl_interp_accel *acc = gsl_interp_accel_alloc();
    gsl_spline *spline = gsl_spline_alloc(gsl_interp_akima, sizet);
    gsl_spline_init(spline, tx, theight,sizet);

    for (i = (int) endterr; i< (int) endterr + (int) ((sizet-1)*refine/space); i++)
    {
        terrain[i] = gsl_spline_eval(spline,xi,acc);
        terrainsl[i] = gsl_spline_eval_deriv(spline,xi,acc);
        xi = xi+(double) space/refine;
    }

    newendterr = endterr + sizet*refine/space;

     hit = intersect(vylift,vxlift,xlift,ylift,terrain,(int) (xlift*refine/space),newendterr);

    landx = hit[0];
    thland = terrainsl[(int) (landx*(double)refine/space)];
        out[0] = hit[1]; /*xland */
        out[1] = hit[2]; /*yland  */
        tflight = (out[0] - xlift)/vxlift;
        out[3] = vylift - g*tflight; /* vyland */
      out[2] = vxlift; /* vxland */
      out[4] = philift + wlift*tflight; /* philand */
      out[5] = wlift; /* wland */
      out[6] = thland;
      out[7] = landx;
      out[8] = (double) newendterr;

// if I pass impulsevecnorm to this function I can still print out it's value using printf here

 return out;
}

double* intersect (double vy, double vx, double currx, double curry, double terrainy[], int counter, int endterr)
{
    double* out = (double *)malloc ( 3*sizeof(double) );
    out[0]=-1;

for (i = counter+1; i < endterr + (sizet-1)*refine; i++)
{
    xball = (double) i*deltax;

    for(j=start; j<endl; j++)
    {
        xt = (double) j*deltax;
        if (pow(xball-xt,2)+pow((vx*vy*(xball-currx)-g*pow(xball-currx,2)+vx*vx*(curry-terrainy[j]))/(vx*vx),2)<= (double) (rball*rball) && j!=counter)
        {
            out[0] = xt;
            out[1] = xball;
            out[2] = (vx*vy*(xball-currx)-g*pow(xball-currx,2)+vx*vx*curry)/(vx*vx);
            flag = 1;
            break;
        }
    }
    if (flag == 1)
    {
        break;
    }
}
return out;
}

double * impulsecalc (double *state)
{
  double *out1 = (double *)malloc ( ((int)(NSTATE/2)) * sizeof(double) );
    out1[0]= (1 - rt)*state[2] - rball*rt*state[5] +
            rball*(MI*state[5] + m*rball*((-1 + rt)*state[2] + rball*rt*state[5]))/
            (MI + m*rball*rball);
    out1[1]= (1 - rn)*state[3];
    out1[2]= state[5] - (MI*state[5] + m*rball*((-1 + rt)*state[2] + rball*rt*state[5]))/
            (MI + m*rball*rball);
  return out1;
}

To make the code shorter I am omitting all variable definitions apart from the pointer definitions. Trust that all other variables have been properly defined. The functions flightdynamics and intersect are long but I didn't want to hide any bit of code for the sake of brevity in case the source of the error was also left out.

I'm an amateur programmer. Started working with C only recently. Any help with this would be greatly appreciated.

Thanks guys. The problem was in the terrain and terrainsl arrays. I initialized them with too little space. Was exceeding array bounds in the for loop in the flightdynamics function.

You are writing to state[4] in your method. If state has less than 5 elements, you are writing to another memory location, which might be impulsevecnorm .

Without any indication what initialize (vx0, vy0); might return, I'd guess that it returns less than 5 elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM