[英]Segmentation fault in my C program
我不明白為什么這會給我一個段錯誤。 有任何想法嗎?
這是返回信號以停止程序的函數(加上在此函數中調用的其他函數):
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,增益= 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上的段錯誤...為什么!?
也許您正在寫完Sol
數組的末尾?
我建議您首先使用調試器(例如gdb)找出導致分段錯誤的行。
就個人而言,我認為對這些常量使用#define
會使函數的可重用性降低。 為什么不通過那些? 至少通過這種方式,您的功能用戶可以通過查看功能來知道需要什么。
我在很多地方都看到魔術數字。 我一點也不在乎這種方法。
因此,此問題已解決。 問題出在內存上。 我正在使用幾個GREAT大小phi [tsteps + 1] [N](N = 2000)等數組。 當用戶(我自己)輸入tsteps時,輸入的數量大約為20,000。 因此,內存過載導致程序崩潰。 謝謝您的所有建議。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.