Я написал этот код, чтобы найти x th наибольших простых чисел:
for (int i = 3 /* 2 has already been added to the list */; i < maxNumber; i += 2) {
for (int tested = 0; ; tested++) {
if (primes[tested] == 0) {
break;
}
if (i % (int) primes[tested] == 0) {
goto loop;
}
}
count++;
if (count == primesSize) {
primesSize += 2000;
primes = (double*) realloc(primes, sizeof(double) * primesSize);
}
primes[count - 1] = i;
printf("Prime number #%d: %d\n", count, i);
printf("Prime size: %d\n", primesSize);
loop: /* statement that does nothing */ if (1) {}
}
Однако при использовании больших чисел (> 8 000) он вернул «исключение с плавающей запятой».
Когда здесь происходит:
- Пользователь выбирает число.
maxNumber
устанавливается в квадратный корень из выбранного числа. - Во-первых, выделяется двойной указатель размером
1000 * sizeof(double)
.Он сохраняется в переменной primes
. - Если число найдено простым, оно добавляется в массив, представленный указателем.
- Когда в массив добавляется 1000-е число, указатель
primes
перераспределяется для хранения еще 2000 номеров.
Когда яиспользовал gdb
, чтобы выяснить причину ошибки, я обнаружил, что эта часть была причиной проблемы:
for (int tested = 0; ; tested++) {
if (primes[tested] == 0) {
break;
}
if (i % (int) primes[tested] == 0 /* breaks here */) {
goto loop;
}
}
Обновление: Я думал, что первый оператор if
будетперехватить эту проблему, потому что printf("%f", primes[tested])
печатает 0. Однако это не так, и "разрыв" не выполняется.
Когда код сломался, tested
был 1001. Я преобразую primes[tested]
вцелое число, потому что для использования по модулю арифметической операции , которую я использую, требуются целые числа.Однако, когда я печатаю primes[tested]
из кода, он показывает 0 .Если я распечатываю значение из gdb, я получаю 6.1501785659964211e-319 .
Чего мне не хватает?Должен ли я изменить свой вызов на realloc
, чтобы избежать этого исключения?