【问题标题】:I am getting a segmentation error in PRIME1 on spoj. How should I eradicate it?我在 spoj 的 PRIME1 中遇到分段错误。我应该如何根除它?
【发布时间】:2016-08-16 15:13:26
【问题描述】:

我对问题PRIME1的回答 请解释我哪里错了。我收到分段错误。

这里是:

    #include<cstdlib>
    #include<iostream>

using namespace std;

int main(int argc, char** argv) {
int t=0,i=0,m=0,n=0;
cin>>t;
while(t--&&t<=10)
{
    cin>>m>>n;
    if(m>=1&&n-m<=100000)
    {
    int prime[n];
    for(i=0;i<n;i++)
        prime[i]=1;
    for (int i=2; i*i<=n; i++)
    { 
    if (prime[i] == true)
    {
        for (int j=i*2; j<=n; j += i)
            prime[j] = false;
    }
    }

    for (int k=m+1; k<n; k++)
        if (prime[k])
            cout <<k<<endl;
    }
}
return 0;
}

【问题讨论】:

  • int prime[n]; 可能太大而无法放入堆栈。它应该类似于char* prime = new char[n];。使用后别忘了delete[]它。 (我不会将此作为答案发布,因为我没有通过提交来检查)
  • bool prime 可能占用更少的空间。 std::vector&lt;bool&gt; 占用的空间要少得多,但性能下降对 SPOJ 没有太大帮助。
  • 不知道为什么这被否决了。也许我需要上学...¯\_(ツ)_/¯
  • 您正在使用 VLA(int prime[n]; 其中n 不是常量表达式)不是标准 C++ 并且可能(gcc 这样做)分配在堆栈中。请遵循@MikeCAT 或@user4581301 的建议。

标签: c++ arrays primes sieve-of-eratosthenes


【解决方案1】:
for (int j=i*2; j<=n; j += i)
prime[j] = false;

这就是导致错误的原因,prime 是一个大小为 n 的数组,这意味着它的最后一个成员的索引是 n-1,这个 for 语句在最后一次迭代时尝试访问 prime[n](j

for(int j=i*2; j<n; ++j)

编辑: 可能由于代码逻辑错误或格式错误导致分段错误,格式化代码后,它编译正常并且不会导致分段错误(尝试输入 {1,2,3} 和 {10,10,10}以及更多组合):

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char** argv) 
{
    int t=0,i=0,m=0,n=0;
    cin>>t;

    while(t--&&t<=10)
    {
        cin>>m;
        cin>>n;
        if(m>=1&&n-m<=100000)
        {
            int prime[n];

            for(i=0;i<n;i++)
            {
                prime[i]=1;
            }

            for (int i=2; i*i<=n; i++)
            { 
                if (prime[i] == true)
                {
                    for (int j=i*2; j<=n; j += i)
                    {
                        cout << "poopy\n";
                        prime[j] = false;
                    }
                }
            }

        for (int k=m+1; k<n; k++)
        {
            if (prime[k])
            {
                cout <<k<<endl;
            }
        }
        }
    }
    return 0;
}

【讨论】:

  • 我在 ubuntu 64 位系统上尝试了代码,它“工作”(没有分段错误,但我不确定逻辑),编辑添加
  • 逻辑没问题。我在ideone上尝试了代码。一切顺利,但 SPOj 中出现了一个奇怪的分段错误:|
猜你喜欢
  • 2016-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-02
  • 2016-06-08
相关资源
最近更新 更多