我试图解决Spoj上的PRIME1问题。我使用Eratosthenes的分段筛来实现这个代码
#include <stdio.h>
long int primes[100000];
int main(void) {
long int t, m, n, i, j, p;
scanf("%ld",&t);
while(t--) {
scanf("%ld",&m);
scanf("%ld",&n);
for(i=2; i*i<=n; i++) {
p=m/i;
p=p*i;
for(j=p; j<=n; j+=i) {
if(j!=i)
primes[j-m] = 1;
}
}
for(i=0; i<(n-m+1); i++) {
if(primes[i] == 0)
printf("%ld ",i+m);
else
continue;
}
printf("\n");
}
return 0;
}
当n-m
的值不是很高时,它的工作正常。但是如果n-m
的值变得非常高(即接近大约100000),则会产生分段错误。为什么会出现这种行为?
另外,当我在main中声明了primes数组时,代码正常工作。
#include <stdio.h>
int main(void) {
long int t, m, n, i, j, p;
scanf("%ld",&t);
while(t--) {
scanf("%ld",&m);
scanf("%ld",&n);
if(m==1) m=2;
long int primes[n-m+1];
for(i=0;i<n-m+1;i++)
primes[i]=0;
for(i=2; i*i<=n; i++) {
p=m/i;
p=p*i;
for(j=p; j<=n; j+=i) {
if(j!=i)
primes[j-m] = 1;
}
}
for(i=0; i<(n-m+1); i++) {
if(primes[i] == 0)
printf("%ld ",i+m);
else
continue;
}
printf("\n");
}
return 0;
}
为什么程序在全局声明质数数组时会出现分段错误?
答案 0 :(得分:2)
在第一个中,您声明primes
具有固定大小100000
,因此如果您尝试访问该范围之外的元素,您将访问不应该访问的内存,因此一段错误。
在第二个示例中,您将其声明为n-m+1
大小,以确保它始终足够大,可以执行您想要的操作。