我的 SPOJ 生成素数的 C++ 程序给出了预期的输出,但最后崩溃了。请让我知道为什么会这样

My C++ program for SPOJ generating primes gives expected output but crashes at the end. Please, let me know why it is happening

我知道代码没有经过优化。我只是想练习埃拉托色尼分段筛法并以不同的方式寻找素数。

我的编译器是 Dev-C++ 5.11。
系统规格:
OS: Windows 8.1 嵌入式专业版
处理器:Intel i5(第三代)
内存:4Gb 不知道是不是硬件兼容性的问题,不过我没用过任何底层程序。

请向我解释程序崩溃的原因。


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#define NUM 1000000
using namespace std;
bool a[NUM]={0};
struct prime10
{
    vector<long long int> primes;
    int max;
    prime10()
    {
        max=NUM;
    }
}p;
void preprocess();
bool ifprime(unsigned long long int n);
void primemn(int m,int n);
int main()
{
    preprocess();
    int t=0;
    scanf("%d",&t);
    for(int i=0;i<t;i++)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        primemn(a,b);
    }
    return 0;
}
void preprocess()
{
    for (int i=2; i<=NUM; i++){
    if (a[i]==0){
        for (int j = i*2; j<=NUM; j+=i){
                a[j]=1;
            }
        }
    }
}
bool ifprime(unsigned long long int n)
{
    if(n<NUM){
        if(!a[n])
        return true;
    }
    else if(n%2==0)
    return false;
    else
    {
        for(int i=3;i<sqrt((long double)n);i+=2)
        {
            if(ifprime(i))
            {
                if(n%i==0)
                return false;
            }
        }
    }
    return true;    
}
void primemn(int m,int n)
{
    if(m<NUM&&n<NUM)
    {
        for(long long int i=m;i<=n;i++)
        {
            if(i==0||i==1)
            {
            }
            else if(!a[i])
            printf("%lld\n",i);
        }
    }
    else if(m<NUM&&n>NUM)
    {
        if(n<=p.max)
        {
            for(long long int i=m;i<NUM;i++)
            {
                if(!a[i])
                printf("%lld\n",i);
            }
            for(int i=0;i<p.primes.size();i++)
            printf("%lld\n",p.primes[i]);
        }
        else if(n>p.max)
        {
            for(long long int i=m;i<NUM;i++)
            {
                if(!a[i])
                printf("%lld\n",i);
            }
            for(int i=0;i<p.primes.size();i++)
            printf("%lld\n",p.primes[i]);
            for(int k=(p.max)+1;k<=n;k++)
            if(ifprime(k)){
            printf("%lld\n",k);
            p.primes.push_back(k);
            p.max=k;
            sort(p.primes.begin(),p.primes.end());
            }
        }
    }
    else if(m>NUM&&n>NUM)
    {
        if(m<=p.max&&n<=p.max)
        for(int o=0;o<p.primes.size();o++)
        {
            if(p.primes[o]>=m&&p.primes[o]<=n)
            printf("%lld\n",o);
        }
        else if(m<=p.max&&n>p.max)
        {
            for(int o=0;o<p.primes.size();o++)
            {
                if(p.primes[o]>=m&&p.primes[o]<=n)
                printf("%lld\n",o);
            }
            for(int o1=(p.max)+1;o1<=n;o1++)
            if(ifprime(o1)){
            printf("%lld\n",o1);
            p.primes.push_back(o1);
            p.max=o1;
            sort(p.primes.begin(),p.primes.end());
            }
        }
        else if(m>p.max&&n>p.max)
        {
            for(int o1=m;o1<=n;o1++)
            if(ifprime(o1)){
            printf("%lld\n",o1);
            p.primes.push_back(o1);
            p.max=o1;
            sort(p.primes.begin(),p.primes.end());
            }
        }   
    }
}

您正在 a 的边界之外写入 - 您的 preprocess 循环应该是 < NUM

越过此边界具有未定义的行为。

可能导致相邻 p 损坏,并且由于 p 的第一个成员是 vector,当vector 被摧毁的可能性很大。

当然还有其他可能的情况,但听起来这就是您的情况。