C++ 西格夫背后的原因?

C++ 西格夫背后的原因?,c++,runtime-error,c++14,C++,Runtime Error,C++14,我正在尝试解决SPOJ上的“主生成器”问题。最初,我使用的是埃拉托斯切尼筛法,但这需要很长时间。所以,我实现了一个分段筛。我的代码在我的机器上运行良好,但是当我将其提交给SPOJ时,我得到消息“runtime error(SIGSEGV)” 通过谷歌搜索,我发现SIGSEGV属于无效内存引用或使用过多内存。我对竞争性编程不熟悉,看不出哪里出了问题 如果有帮助的话,我正在使用CPP14-CLANG语言 代码如下: #include <iostream> #include <str

我正在尝试解决SPOJ上的“主生成器”问题。最初,我使用的是埃拉托斯切尼筛法,但这需要很长时间。所以,我实现了一个分段筛。我的代码在我的机器上运行良好,但是当我将其提交给SPOJ时,我得到消息“runtime error(SIGSEGV)”

通过谷歌搜索,我发现SIGSEGV属于无效内存引用或使用过多内存。我对竞争性编程不熟悉,看不出哪里出了问题

如果有帮助的话,我正在使用CPP14-CLANG语言

代码如下:

#include <iostream>
#include <string.h>
#include <math.h>
#include <vector>
#include <sstream>

int main(){
    int nt=0, l_value=0, r_value=0, v=1;
    int lr_array[20] = {0};
    std::vector <int> soe;
    std::vector <std::string> token;
    std::vector <int> prime_list(1e5, 1);

    //take number of test cases and their respective range
    std::cin>>nt;
    std::cin.ignore();

    for(int i=0;i<nt;i++)
    {
        std::string line;
        getline(std::cin, line);
        std::stringstream check1(line);
        std::string intermediate;
        while(getline(check1, intermediate, ' '))
        {
            token.push_back(intermediate);
        }

        for(int i=0;i<token.size();i++)
        {
            lr_array[i] = std::stoi(token[i]);
        }

    }


    //Find out primes till sqrt(y) by using Sieve of Erathosthenes
    for(int i=0;i<=32000;i++)
    {
        soe.push_back(1);
    }

    for(int k=2;k<32000;k++)
    {
        if(soe[k])
        {

            for(int j=(k*k);j<=32000;j+=k)
            {
                soe[j] = 0;
            }
        }
    }

    //Use each element from SoE list to determine non-primes in given range

    for(int i=0;i<nt;i++)
    {
        for(int j=2;j<soe.size();j++)
        {
            if(soe[j] && (j<=lr_array[i+v]))
            {
                int temp = int((lr_array[2*i]/j));
                temp = temp*j;
                if(temp<lr_array[2*i]){
                    temp += j;
                }

                for(int k=lr_array[2*i];k<=lr_array[i+v];k++)
                {
                    if(k==lr_array[2*i])
                        {
                            if(j==2){prime_list[temp]=0;continue;}
                            else{temp+=j;prime_list[temp]=0;continue;}

                        }
                    if(temp<=lr_array[i+v])
                    {
                        prime_list[temp]=0;
                        temp += j;
                    }
                    else{
                        break;
                    }

                }
            }

        }

        if(lr_array[2*i]<=2){prime_list[2]=1;}

        for(int l=lr_array[2*i];l<=lr_array[i+v];l++){
            if(prime_list[l]==1)
            {
                std::cout<<l<<std::endl;
            }

    }
        v++;
        std::cout<<std::endl;       
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
int main(){
int nt=0,l_值=0,r_值=0,v=1;
int lr_数组[20]={0};
std::向量soe;
std::向量令牌;
向量素数表(1e5,1);
//获取测试用例的数量及其各自的范围
标准:cin>>nt;
std::cin.ignore();

对于(int i=0;i当代码试图访问未分配的内存部分时,会发生分段错误。如果运气不好,您可能会发现代码执行“良好”。也就是说,内存损坏发生时。进程写入已分配但不属于感兴趣数组的内存块

在内部循环中,您试图访问的
soe
内存远远超过分配的内存。它超出了内存范围(如果幸运的话),或者破坏了其他变量(如果不幸运的话)


for(int k=2;kUsing太多内存
lr_数组
只有20个元素大,你能在它之外索引吗?我看不到任何检查。我是新加入竞争性编程的人——请阅读。谷歌关于这一点告诉我SIGSEGV…-“谷歌”因为SIGSEGV不能准确地告诉您程序有什么问题。调试程序会告诉您程序有什么问题。您不会在代码中检查循环是否超过数组大小。请注意,您可以使用
soe.resize(32001,1)
而不是逐个推回32001个。@PaulMcKenzie,谢谢你的链接。我因此修复了24个警告。因此,我确实得到了std::out_of u range异常!我认为问题是prime_list,因为初始大小为1e5时,它的计算量没有超过100000,而大小为1e3时,它的计算量也没有超过1000001000.我现在得到了一条“错误答案”信息,这比我以前得到的要好得多。谢谢!我相信
soe
的最大索引实际上是32000,因为之前的循环是
for(int I=0;如果不在调试器中运行它,我无法判断,但是…问题很可能早就出现在
lr\u数组[I]=std::stoi(令牌[I])
。这是假设有超过20个令牌,最有可能是这种情况。无论如何,相同的问题。固定长度与任意长度。
push_back
在(int i=0;i)的循环的每次迭代中都会发生
for(int k=2;k<32000;k++)
{
    if(soe[k])
    {

        for(int j=(k*k);j<=32000;j+=k)
        // j grows up to 32000. Largesr valid index for soe is 31999
        {
            soe[j] = 0; // <====== This is where segfault happens
        }
    }
}