[英]How to find a problem in a C program : Program received signal SIGSEGV, Segmentation fault
I have a problem with a C program. 我有一个C程序的问题。 It was working before I made some changes (from define do var declarations). 它在我进行一些更改之前工作(来自define do var声明)。 Now: 现在:
gcc mc -lm -Wall -march=native
它使用以下命令编译而没有错误: gcc mc -lm -Wall -march=native
So I tried to find a problem using gdb. 所以我尝试使用gdb找到问题。 Now I know more: 现在我知道了更多:
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;
The problem is in function (which code was not changed), code below. 问题在于功能(代码没有改变),代码如下。
How can I find the problem? 我怎样才能找到问题?
gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9) 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;
}
Program received signal SIGSEGV, Segmentation fault. 程序接收信号SIGSEGV,分段故障。 0x0000000000400bbb in GivePeriod (Cx=-0,75, Cy=-0, Iteration_Max=650000, precision=0,00033329999999999997) at mc:137 137 orbit[0][0]=0.0; GivePeriod中的0x0000000000400bbb(Cx = -0,75,Cy = -0,Iteration_Max = 650000,精度= 0,00033329999999999997),mc:137 137 orbit [0] [0] = 0.0;
double orbit[Iteration_Max+1][2];
650001 * 2 * 8 (bytes/double) = 10400016 650001 * 2 * 8(字节/双)= 10400016
That's probably bigger than your maximum stack size; 这可能比你的最大堆栈大小更大; 1 on linux you can check that with ulimit -s
and by default it is 8192 kB. 1在linux上你可以用ulimit -s
检查它,默认情况下它是8192 kB。
If you need storage that big, allocate it on the heap with malloc()
and free()
it when done. 如果你需要大的存储空间,请在完成后使用malloc()
和free()
它分配到堆上 。
1. Memory in a C program is broken into two main areas: the heap , which contains globals and dynamically allocated things (and grows with them), and the small fixed size stack , which is a LIFO structure onto which local data is pushed. 1. C程序中的内存分为两个主要区域: 堆 ,它包含全局变量和动态分配的东西(并随之增长),以及小的固定大小堆栈 ,它是一个LIFO结构,在其上推送本地数据 。 Since array orbit
is declared in a function and not allocated dynamically, it is local data and pushed onto the stack. 由于数组orbit
是在函数中声明的而不是动态分配的,因此它是本地数据并被压入堆栈。 When a function exits, its local data is popped off the stack and discarded. 当函数退出时,其本地数据将从堆栈中弹出并被丢弃。
You're probably blowing your stack. 你可能正在吹嘘你的筹码。 That orbit
array weighs something like 10 megabytes, too much for a stack allocation. 该orbit
阵列的重量大约为10兆字节,对于堆栈分配来说太多了。
Allocate it on the heap with malloc
or calloc
, and don't forget to free
it on every path that exits your function. 使用malloc
或calloc
在堆上分配它,并且不要忘记在退出函数的每个路径上free
它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.