【问题标题】:Segmentation fault in my C program我的 C 程序中的分段错误
【发布时间】:2010-05-02 22:04:12
【问题描述】:

我不明白为什么这会给我一个段错误。有什么想法吗?

这是返回信号停止程序的函数 (加上在此调用的其他函数):

double bisect(double A0,double A1,double Sol[N],double tol,double c)
{
  double Amid,shot;

  while (A1-A0 > tol) {
    Amid = 0.5*(A0+A1);

    shot = shoot(Sol, Amid, c);

    if (shot==2.*Pi) {
      return Amid;
    }

    if (shot > 2.*Pi){
      A1 = Amid;
    }
    else if (shot < 2.*Pi){
      A0 = Amid;
    }
  }

  return 0.5*(A1+A0);
}

double shoot(double Sol[N],double A,double c)
{
  int i,j;

  /*Initial Conditions*/
  for (i=0;i<buff;i++)
    {
      Sol[i] = 0.;
    }
  for (i=buff+l;i<N;i++)
    {
      Sol[i] = 2.*Pi;
    }
  Sol[buff]= 0;
  Sol[buff+1]= A*exp(sqrt(1+3*c)*dx);


  for (i=buff+2;i<buff+l;i++)
    {
      Sol[i] = (dx*dx)*( sin(Sol[i-1]) + c*sin(3.*(Sol[i-1])) )
 - Sol[i-2] + 2.*Sol[i-1];
    }

  return Sol[i-1];
}

价值观 buff、l、N 使用#define 语句定义。 l = 401,buff = 50,N = 2000

这里是完整的代码:

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

#define w 10    /*characteristic width of a soliton*/
#define dx 0.05 /*distance between lattice sites*/
#define s (2*w)/dx  /*size of soliton shape*/
#define l (int)(s+1)   /*array length for soliton*/
#define N (int)2000    /*length of field array--lattice sites*/
#define Pi (double)4*atan(1)
#define buff (int)50


double shoot(double Sol[N],double A,double c);
double bisect(double A0,double A1,double Sol[N],double tol,double c);
void super_pos(double antiSol[N],double Sol[N],double phi[][N]);
void vel_ver(double phi[][N],double v,double c,int tsteps,double dt);



int main(int argc, char **argv)
{
  double c,Sol[N],antiSol[N],A,A0,A1,tol,v,dt;
  int  tsteps,i;
  FILE *fp1,*fp2,*fp3;

  fp1 = fopen("soliton.dat","w");
  fp2 = fopen("final-phi.dat","w");
  fp3 = fopen("energy.dat","w");
  printf("Please input the number of time steps:");
  scanf("%d",&tsteps);
  printf("Also, enter the time step size:");
  scanf("%lf",&dt);
  do{
    printf("Please input the parameter c in the interval [-1/3,1]:");
    scanf("%lf",&c);}
  while(c < (-1./3.) || c > 1.);
  printf("Please input the inital speed of eiter soliton:");
  scanf("%lf",&v);

  double phi[tsteps+1][N];

  tol = 0.0000001;
  A0 = 0.;
  A1 = 2.*Pi;
  A = bisect(A0,A1,Sol,tol,c);
  shoot(Sol,A,c);
  for (i=0;i<N;i++)
    {
      fprintf(fp1,"%d\t",i);
      fprintf(fp1,"%lf\n",Sol[i]);
    }
  fclose(fp1);
  super_pos(antiSol,Sol,phi);
  /*vel_ver(phi,v,c,tsteps,dt);
  for (i=0;i<N;i++){
    fprintf(fp2,"%d\t",i);
    fprintf(fp2,"%lf\n",phi[tsteps][i]);
    }*/


}


double shoot(double Sol[N],double A,double c)
{
  int i,j;

  /*Initial Conditions*/
  for (i=0;i<buff;i++)
    {
      Sol[i] = 0.;
    }
  for (i=buff+l;i<N;i++)
    {
      Sol[i] = 2.*Pi;
    }
  Sol[buff]= 0;
  Sol[buff+1]= A*exp(sqrt(1+3*c)*dx);


  for (i=buff+2;i<buff+l;i++)
    {
      Sol[i] = (dx*dx)*( sin(Sol[i-1]) + c*sin(3.*(Sol[i-1])) )
    - Sol[i-2] + 2.*Sol[i-1];
    }

  return Sol[i-1];
}


double bisect(double A0,double A1,double Sol[N],double tol,double c)
{
  double Amid,shot;

  while (A1-A0 > tol) {
    Amid = 0.5*(A0+A1);

    shot = shoot(Sol, Amid, c);

    if (shot==2.*Pi) {
      return Amid;
    }

    if (shot > 2.*Pi){
      A1 = Amid;
    }
    else if (shot < 2.*Pi){
      A0 = Amid;
    }
  }

  return 0.5*(A1+A0);
}


void super_pos(double antiSol[N],double Sol[N],double phi[][N])
{
  int i;

  /*for (i=0;i<N;i++)
    {
    phi[i]=0;
    }

  for (i=buffer+s;i<1950-s;i++)
    {
      phi[i]=2*Pi;
      }*/

  for (i=0;i<N;i++)
    {
      antiSol[i] = Sol[N-i];
    }

  /*for (i=0;i<s+1;i++)
    {
      phi[buffer+j] = Sol[j];
      phi[1549+j] = antiSol[j];
      }*/

  for (i=0;i<N;i++)
    {
      phi[0][i] = antiSol[i] + Sol[i] - 2.*Pi;
    }

}

/* This funciton will set the 2nd input array to the derivative at the time t, for all points x in the lattice */
void deriv2(double phi[][N],double DphiDx2[][N],int t)
{
  //double SolDer2[s+1];
  int x;
  for (x=0;x<N;x++)
    {
      DphiDx2[t][x] = (phi[buff+x+1][t] + phi[buff+x-1][t] - 2.*phi[x][t])/(dx*dx);
    }

  /*for (i=0;i<N;i++)
    {
      ptr[i] = &SolDer2[i];
      }*/

  //return DphiDx2[x];
  }




void vel_ver(double phi[][N],double v,double c,int tsteps,double dt)
{
  int t,x;
  double d1,d2,dp,DphiDx1[tsteps+1][N],DphiDx2[tsteps+1][N],dpdt[tsteps+1][N],p[tsteps+1][N];

  for (t=0;t<tsteps;t++){
    if (t==0){
      for (x=0;x<N;x++){//inital conditions
    deriv2(phi,DphiDx2,t);
    dpdt[t][x] = DphiDx2[t][x] - sin(phi[t][x]) - sin(3.*phi[t][x]);
    DphiDx1[t][x] = (phi[t][x+1] - phi[t][x])/dx;
    p[t][x] = -v*DphiDx1[t][x];
      }
    }
    for (x=0;x<N;x++){//velocity-verlet
      phi[t+1][x] = phi[t][x] + dt*p[t][x] + (dt*dt/2)*dpdt[t][x];
      p[t+1][x] = p[t][x] + (dt/2)*dpdt[t][x];
      deriv2(phi,DphiDx2,t+1);
      dpdt[t][x] = DphiDx2[t][x] - sin(phi[t+1][x]) - sin(3.*phi[t+1][x]);
      p[t+1][x] += (dt/2)*dpdt[t+1][x];
    }
  }  
}

所以,这真的不是因为我覆盖了 Sol 数组的末尾。我已经注释掉了我怀疑会导致问题的两个功能(平分或拍摄)并插入了打印功能。发生了两件事。当我有如下代码时:

double A,Pi,B,c;

c=0;
Pi = 4.*atan(1.);
A = Pi;
B = 1./4.;
printf("%lf",B);
B = shoot(Sol,A,c);
printf("%lf",B);

我从函数中得到一个段错误,射击。但是,如果我拿掉拍摄功能,那么我就有了:

double A,Pi,B,c;

c=0;
Pi = 4.*atan(1.);
A = Pi;
B = 1./4.;
printf("%lf",B);

它在 printf 处给了我一个段错误...为什么!?

【问题讨论】:

  • 请贴出完整的代码(并修复代码块)。然而,segv 肯定发生在 Sol 访问上。通过 valgrind 或在您最喜欢的调试器中运行它。
  • “shoot”中的代码似乎引用了一个未定义的变量“dx”和另一个“Pi”(并包含一个未使用的变量“j”)。
  • @sth: segfault 是由 main 中的 bisect fxn 调用的。 @J.Leffler:拍摄功能中的 sode 可以使用 Pi,因为我使用 #define 定义了它。可能不是最有说服力的选择,但一旦我能正常工作,我会解决这个问题

标签: c segmentation-fault


【解决方案1】:

也许您正在写超过Sol 数组的末尾?

我建议您首先使用诸如 gdb 之类的调试器来找出导致分段错误的行。

【讨论】:

  • 我知道哪一行——或者至少在我的调用代码中。我使用了 ddd,信号位于我的代码 w/main 的第 45 行,这是我称之为 bisect 的行。而且 Sol 的大小比 buff+l 大得多,我只用 N 循环一次,我已经检查并仔细检查了我的 i
【解决方案2】:

就个人而言,我认为将#define 用于这些常量会使您的函数的可重用性降低。为什么不把那些传进去?至少这样,您的函数的用户通过查看函数就知道需要什么。

我在很多地方都看到了神奇的数字。我根本不喜欢这种方法。

【讨论】:

  • 当然,当然。我自己反对幻数。我只是想让它先运行。不过我会把剩下的代码放上去
【解决方案3】:

所以,这个问题已经解决了。问题出在内存上。我正在使用几个大小为 phi[tsteps+1][N] (N=2000) 等的数组。当 tsteps 来自用户(我自己的)输入时,它大约为 20,000。因此,内存过载导致程序在运行时崩溃。谢谢大家的建议,大家。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 2018-11-18
    • 2011-05-23
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    相关资源
    最近更新 更多