Ошибка SIGABRT в C ++

0

Я получаю ошибку SIGABRT, когда компилирую следующий код. (PRIME1 проблема spoj). Ссылка на проблему - 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
    Для начала, int a[(2*size)-1]; является (1) недопустимым C ++ (VLA является расширением GCC) и (2) неправильно вычисляет размер массива.
Теги:

3 ответа

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 может запрашивать до 8 ГБ памяти, в зависимости от значения sizeof(long) в используемой вами системе. Выделение почти наверняка будет терпеть неудачу, std::bad_alloc исключение std::bad_alloc которое вызывает std::bad_alloc std::abort(), поскольку у вас нет кода обработки исключений.

  • 0
    «р» - самое большое число, которое мы дали в качестве входных данных. Я использовал сито Эратосфена, чтобы решить проблему. Так что я нашел все простые числа до 'p'
  • 0
    @ user3757655 Ваш цикл do-while на самом деле не делает это правильно; но это в сторону, вы все еще пытаетесь new до массива , который может быть столь же большой , как 4 Гб (при условии 32-бит) с учетом ограничений , предусмотренных, которые просто не будут работать.
Показать ещё 3 комментария
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-индексируются).

У вас тогда есть такие вещи:

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

Какая петля до l == 2*size-1, поэтому l+3 недействителен, как только вы нажмете 2 * size - 1 - 3.

В основном у вас просто много мест, где вы читаете или записываете конец конца массива или не обеспечиваете правильную инициализацию и вызывают неопределенное поведение.

  • 0
    Насколько я понимаю, с этими сайтами они гарантируют, что входные данные находятся в указанном диапазоне, поэтому вам не нужно делать дополнительную проверку этого.
  • 0
    @TC: Достаточно справедливо, это было больше в стороне. Я удалил это.
Показать ещё 2 комментария
0

Вы получаете доступ к элементу массива, обращающемуся за пределами границ

Размер массива 2*size-1 Итак, элементы от 0 до 2*size-2

Но в вашем цикле for вы увеличиваете 2*size до 2*size тем самым получаете доступ к 2*size-1 который находится за пределами границ

Ещё вопросы

Сообщество Overcoder
Наверх
Меню