编译以下代码时出现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;
}
答案 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+3
,2 * 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
设置为p
到a[1]
的简单情况,或者您读入的第二个数字。那个界限是什么?号码?
问题是边界是n <= 1000000000
,或10 9 。您的new
可以请求多达8GB的内存,具体取决于您使用的系统中sizeof(long)
的值。分配几乎肯定会失败,抛出std::bad_alloc
异常会导致std::abort()
被调用,因为您没有任何异常处理代码。