如何在C程序中找到问题:编程接收信号SIGSEGV,分段故障

时间:2014-01-04 11:57:40

标签: gcc c gdb

我的C程序有问题。它在我进行一些更改之前工作(来自define do var声明)。 现在:

  • 使用gcc m.c -lm -Wall -march=native
  • 编译时没有错误
  • 有运行时错误:分段错误

所以我尝试使用gdb找到问题。现在我知道了更多:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400bbb in GivePeriod (Cx=-0,75, Cy=-0, Iteration_Max=650000, 
    precision=0,00033329999999999997) at m.c:137
137    orbit[0][0]=0.0;

问题在于功能(代码没有改变),代码如下。

如何找到问题?

gcc版本4.8.1(Ubuntu / Linaro 4.8.1-10ubuntu9)

/*-------------------------------*/
// this function is based on program:
// Program MANCHAOS.BAS  
// http://sprott.physics.wisc.edu/chaos/manchaos.bas
// (c) 1997 by J. C. Sprott 
//
int GivePeriod(double Cx,double Cy, int Iteration_Max, double precision)
{  
 double Zx2, Zy2, /* Zx2=Zx*Zx;  Zy2=Zy*Zy  */
     ZPrevieousX,ZPrevieousY,
     ZNextX,ZNextY;
   int Iteration,
  I;  
double orbit[Iteration_Max+1][2]; /* array elements are numbered from 0 to   length-1 */    
 /* starting point is critical point  */
ZPrevieousX=0.0;
ZPrevieousY=0.0;
orbit[0][0]=0.0;
orbit[0][1]=0.0;  
Zx2=ZPrevieousX*ZPrevieousX;
Zy2=ZPrevieousY*ZPrevieousY;
/* iterate and save points for analysis */
for (Iteration=1;Iteration<Iteration_Max+1 ;Iteration++)
    {
        ZNextY=2*ZPrevieousX*ZPrevieousY + Cy;
        ZNextX=Zx2-Zy2 +Cx;
        Zx2=ZNextX*ZNextX;
        Zy2=ZNextY*ZNextY;
        if ((Zx2+Zy2)>ER2) return 0; /* basin of atraction to infinity */
        //if   (SameComplexValue(ZPrevieousX,ZPrevieousY,ZNextX,ZNextY,precision))
        //   return 1; /* fixed point , period =1 */
        ZPrevieousX=ZNextX;
        ZPrevieousY=ZNextY;
        /* */
        orbit[Iteration][0]=ZNextX;
        orbit[Iteration][1]=ZNextY;   

    }; 
 /* here iteration=IterationMax+1 but last element of orbit has number  IterationMax */    
 for(I=Iteration_Max-1;I>0;I--) 
  if (SameComplexValue(orbit[Iteration_Max][0],orbit[Iteration_Max] [1],orbit[I][0],orbit[I][1],precision))
    return(Iteration_Max-I);
 return 0;
}

2 个答案:

答案 0 :(得分:7)

  

编程接收信号SIGSEGV,分段故障。 GivePeriod中的0x0000000000400bbb(Cx = -0,75,Cy = -0,Iteration_Max = 650000,精度= 0,00033329999999999997)at m.c:137 137 orbit [0] [0] = 0.0;

double orbit[Iteration_Max+1][2];

650001 * 2 * 8(字节/双精度)= 10400016

这可能比你的最大堆栈大小要大; 1 在linux上你可以用ulimit -s检查它,默认情况下它是8192 kB。

如果您需要大容量存储,请在完成时将其分配到,并使用malloc()free()


1。 C程序中的内存分为两个主要区域: heap ,它包含全局变量和动态分配的东西(并随之增长),以及小的固定大小 stack < / em>,这是一个LIFO结构,在其上推送本地数据。由于数组orbit在函数中声明而未动态分配,因此它是本地数据并被压入堆栈。当函数退出时,其本地数据将从堆栈中弹出并被丢弃。

答案 1 :(得分:4)

你可能正在吹嘘你的筹码。那个orbit数组的重量大约是10兆字节,对于堆栈分配来说太多了。

使用malloccalloc在堆上分配它,并且不要忘记在退出函数的每条路径上free