在Spoj上PRIME1的这种分段错误的原因是什么?

时间:2015-07-07 15:57:34

标签: c arrays segmentation-fault

我试图解决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;
    }

为什么程序在全局声明质数数组时会出现分段错误?

1 个答案:

答案 0 :(得分:2)

在第一个中,您声明primes具有固定大小100000,因此如果您尝试访问该范围之外的元素,您将访问不应该访问的内存,因此一段错误。

在第二个示例中,您将其声明为n-m+1大小,以确保它始终足够大,可以执行您想要的操作。