该代码是礼品包装算法的实现。输入文件每行的格式为"X Y Z",我不需要考虑 Z 坐标。该代码适用于较小的 N(如 100000),但对于较大的 N 值,会出现分段错误。有人可以解释一下原因吗?
#include <stdio.h>
#include <stdlib.h>
#define N 200000
struct Point{
double x,y;
};struct Point p[N];
int ori(struct Point p1, struct Point p2, struct Point p3);
int main(){
FILE *fp,*fp2;
fp2=fopen("out.txt","w");
int i=0;
fp=fopen("sample.txt","r");
if(fp==NULL){
printf("File not found!n");
exit(0);
}
double g;
for(i=0;i<N;i++)
fscanf(fp,"%lf %lf %lf",&p[i].x,&p[i].y,&g);
int l=0;
for(i=1;i<N;i++){
if(p[i].x<p[l].x){
l=i;
}
}
int base=l,q;
int chullin[N];
for(i=0;i<N;i++)
chullin[i]=-1;
while(true){
q=(base+1)%N;
for(i=0;i<N;i++)
if(ori(p[base],p[i],p[q])==1)
q=i;
chullin[base]=q;
base=q;
if(base==l)
break;
}
int cnt=0;
int a[26];
for(i=0;i<N;i++)
if(chullin[i]!=-1){
a[i]=i;
fprintf(fp2,"%f %f %dn",p[i].x,p[i].y,i);
cnt++;
}
return 0;
}
int ori(struct Point p1, struct Point p2, struct Point p3){
int val=p1.x*(p2.y-p3.y)-p1.y*(p2.x-p3.x)+(p2.x*p3.y-p3.x*p2.y);
if(val==0)
return 0;
if(val>0)
return 1;
else return -1;
}
您完全溢出了 int 数组 'a' 或至少访问了堆栈上数组中不存在的值......如果丘林[i] != -1 超过 26 分...或者,如果 chullin[i] 在 i>25 的地方,您正在堆栈上写入随机数。
int a[26];
for(i=0;i<N;i++)
if(chullin[i]!=-1){
a[i]=i; //problem here.
fprintf(fp2,"%f %f %dn",p[i].x,p[i].y,i);
cnt++;
}
问题不在于数组p
,而在于数组chullin
。尝试使用 malloc 函数动态分配数组:
int *chullin = (int*)malloc(sizeof(int)*N);
// do whatever you want with chullin
free(chullin);
编辑:我将尝试解释分段错误的原因。在函数内创建非动态数组时,该数组将在堆中分配。堆的大小有限,因此当您声明大型数组时,堆会溢出。使用 malloc
时,您可以动态分配数组,这意味着它在堆栈中分配。堆栈的大小比堆大得多,因此您可以创建更大的数组。全局数组也在堆栈中分配,这就是为什么您不需要动态分配它们的原因......
编辑[2]:数组a
的大小26
,这意味着当N大于或等于26
时,您将访问无效的内存位置,从而导致分段错误。