C ++中的SIGABRT错误

时间:2014-06-20 04:03:47

标签: c++

编译以下代码时出现SIGABRT错误。(错误的PRIME1问题)。 问题的链接是http://www.spoj.com/problems/PRIME1/。它在代码块上运行良好但是spoj返回SIGABRT错误。有人可以解释原因吗?

int main()
{

    long long k,x,j=0,size,l=0,p=0,q=0,r=0,s;
    cin>>size;
    int a[(2*size)];
    cout<<endl;
    for(int i=0; i< (2*size); i++)
    {
        cin>>a[i];
    }
    if( size == 1)
    {
        p=a[1];

    }
    else
    {
        do
        {
            if(a[l+3]>a[l+1])
            {
                p=a[l+3];
            }
            else
            {
                p=a[l+1];
            }
            l=l+2;
        }while(l<2*(size-1));
    }
    cout<<p;
    long * b = new long [p-1];
    for(long long i=0;i<p-1;i++)
    {
        b[i]=1;
    }
    b[0]=b[1]=0;
    s=sqrt(p)
    for(long long i = 2; i <= s; i++)
    {
        if(b[i] == 1)
        {
            for(long long j = i*i; j <= p; j = j + i)
            {
                b[j] = 0;
            }
        }
    }
    while(r<(2*size))
    {
       for(long long i = a[r];i < a[r+1];i++)
        {
            if(b[i] == 1 )
            {
                cout << i << "\n";
            }
        }
    cout<<endl;
    r=r+2;
    }
    delete [] b;
}

3 个答案:

答案 0 :(得分:0)

您将a初始化为2 * size - 1个元素......

int a[(2*size)-1];

但是你写了2 * size个元素。

for(int i=0; i< (2*size); i++)
// ...

你的循环应该是:

for(int i=0; i< (2*size-1); i++)

下一步...

if(size == 1)
{
    p=a[1];
}

如果size == 1然后您分配了一个2 * 1 - 1 = 1元素数组,那么a[1]是无效访问(您只有a[0]因为数组是0索引的。)< / p>

然后你有这样的东西:

if(a[l+3]>a[l+1])

l == 2*size-1之前循环播放,因此只要您点击l+32 * size - 1 - 3就会无效。

基本上,您只有很多地方可以在数组末尾读取或写入,或者无法确保正确初始化和调用未定义的行为。

答案 1 :(得分:0)

您正在访问访问外部边界的数组元素

数组大小2*size-1因此从0到2*size-2

的元素

但是在你的for循环中,你要前往2*size,从而访问超出界限的2*size-1

答案 2 :(得分:0)

int a[(2*size)-1]; 

这不是合法的C ++代码(它使用的是GCC扩展名),但它显然是编译的,所以我们将允许这样的幻灯片。您将在以下循环中访问您的数组,并在以后的所有地方访问,这是未定义的行为 - 您需要一个大小为2 * size的数组来读取所有提供的参数。虽然他们保证size <= 10,但您也可以将其声明为int a[20];

但这可能并没有导致崩溃。导致崩溃的原因可能是这一行:

long * b = new long [p-1];

p是什么?好吧,我们只考虑将size = 1设置为pa[1]的简单情况,或者您读入的第二个数字。那个界限是什么?号码?

问题是边界是n <= 1000000000,或10 9 。您的new可以请求多达8GB的内存,具体取决于您使用的系统中sizeof(long)的值。分配几乎肯定会失败,抛出std::bad_alloc异常会导致std::abort()被调用,因为您没有任何异常处理代码。