Что вызывает ошибку сегментации?
-
21-09-2019 - |
Вопрос
Я пытался написать программу, которая определит, является ли число простым или нет.Я основал его на Сите Эратосфена.В любом случае, моя программа работает для небольших чисел (работает 15485863), но если я использую большие числа (напр.17485863) Я получаю ошибку сегментации.Я использую длинные значения без знака и не думаю, что превысил их максимальное значение.Я просто не вижу, что я сделал не так.Заранее благодарю вас за любую помощь!
#include <iostream>
#include <limits>
using namespace std;
bool soe (unsigned long long);
int main (void)
{
unsigned long long x = 17485863;
bool q = soe(x);
cout << x << " is ";
if(q)
cout << "prime." << endl;
else
cout << "not prime." << endl;
return 0;
}
bool soe(unsigned long long input)
{
unsigned long long arrayLength = input%2 + input/2;
unsigned long long index = 2;
unsigned long long greatestMult = 0;
bool array[arrayLength];
array[0] = true; //ignore true values in the array
array[1] = true;
do{
array[index] = false;
}while(++index < arrayLength);
index = 2;
do
{
if(input%index != 0)
{
greatestMult = input/index;
while(index*greatestMult > arrayLength)
greatestMult--;
do
{
array[index*greatestMult] = true;
}while(--greatestMult > 0);
do
{
if(!array[index])
break;
}while(++index < arrayLength);
}
else
{
cout << endl << input << " is divisble by " << index << endl;
return false;
}
}while(index < arrayLength);
return true;
}
Решение
В строке 24 у вас есть: bool array[arrayLength];
Вы не можете объявить массив в стеке подобным образом.Программа завершает работу в строке 29.Вам нужно объявить это в куче, используя new / delete;
Что-то в этом роде (возможно, у меня там одна-две утечки, но вы поняли идею);
//Beginning on Line 28
bool *array = new bool[arrayLength];
array[0] = true; //ignore true values in the array
array[1] = true;
do{
array[index] = false;
}while(++index < arrayLength);
index = 2;
do
{
if(input%index != 0)
{
greatestMult = input/index;
while(index*greatestMult > arrayLength)
greatestMult--;
do
{
array[index*greatestMult] = true;
}while(--greatestMult > 0);
do
{
if(!array[index])
break;
}while(++index < arrayLength);
}
else
{
cout << endl << input << " is divisble by " << index << endl;
delete [] array;
return false;
}
}while(index < arrayLength);
delete [] array;
return true;
}
Выходной сигнал
g++ -g test.cpp
gdb ./a.out
...clipped...
(gdb) run
Starting program: /Users/nextraztus/a.out
Reading symbols for shared libraries ++. done
17485863 is divisble by 3
17485863 is not prime.
Program exited normally.
(gdb)
Другие советы
Пожалуйста, обратите внимание, что ни long long, ни использование переменных для измерения автоматических массивов не являются частью C ++ - они являются расширениями, предоставляемыми gcc, и их не следует использовать, если проблема с переносимостью.
Чтобы решить вашу проблему, определите размер массива следующим образом:
bool array[arrayLength];
вызовет переполнение стека (и, следовательно, ошибку seg), если значение arrayLength слишком велико.Вместо этого используйте std::vector, но имейте в виду, что память - это не бесконечный ресурс.
Возможно, что индекс *greatestMult будет равен arrayLength , поэтому вы можете перезаписать последний элемент после конца массива.
Кроме того, подобное выделение больших массивов в стеке может вызвать проблему в зависимости от операционной системы.Некоторые системы настолько сильно расширят стек, что другие не смогут этого сделать.