【问题标题】:What is the reason of this Segmentation fault for PRIME1 on Spoj? [closed]Spoj 上 PRIME1 的这种分段错误的原因是什么? [关闭]
【发布时间】:2015-07-07 15:57:33
【问题描述】:

我正在尝试解决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 中声明素数数组时,代码可以正常工作。

    #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;
    }

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

【问题讨论】:

  • 也许你超出了数组的范围?或者您可能需要unsigned long longlong 可能只有 32 位并且您正在溢出)?
  • n-m max = 100000, i&lt;(n-m+1) : i max = n-mprimes[100000]; 所以primes[i]=0; (primes[100000] = 1) 超出范围。
  • 当用户运行程序时,他们会留下一个闪烁的光标,并且不知道他们应该输入什么。 Suggest:提示用户输入三个输入值中的每一个。始终检查 scanf() 的返回值以确保操作成功
  • @user3629249 该程序适用于 SPOJ。
  • 感谢@BLUEPIXY。它非常有帮助。

标签: c arrays segmentation-fault


【解决方案1】:

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

在第二个示例中,您声明它的大小为 n-m+1,这将确保它始终足够大,可以满足您的需求。

【讨论】:

  • 没有。即使 n-m 的值在 100000 以内或接近 100000,例如 99999,它也显示出分段错误。
  • 如果n-m
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 2016-10-18
  • 2013-06-16
  • 2015-04-23
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多