Ошибка сегмента при инициализации массива в C ++ (проект Эйлера № 3)

0

Поэтому я пытаюсь написать программу для решения проблемы Project Euler с наибольшим основным фактором, и, хотя я знаю, что код является структурно правильным (поскольку он возвращает правильные ответы для меньших чисел, включая пример 13195, который они дают), я продолжайте получать ошибку сегментации, когда я вводим номер, который мы должны решить, то есть 600851475143. Код выглядит следующим образом:

#include <stdio.h>
#include <math.h>

main(){
    int number,a,b,c,i,j,n,gpf;
    printf("Input number to analyze: ");
    scanf("%d",&number);
    a = number/2;
    printf("%d\n",a);
    int* primesieve = new int[a+1];               /*IMPORTANT LINE*/
    for (i=0;i<a+1;i++){
        primesieve[i] = 1;
    }
    for (j=2;j<=a;j++){
        if (primesieve[j] == 1){
            for (c=2;j*c<=a;c++){
                primesieve[j*c] = 0;
            }
        }
    }
    for (n=2;n<=a;n++){
        b = number/n;
        printf("%d\n",b);
        if (number % n == 0){
            if (primesieve[b] == 1){
                gpf = b;
                n = a+1;
            }
        }
    }
    delete[] primesieve;
    printf("The greatest prime factor of %d is %d.\n",number,gpf);
}

Проблема возникает из инициализации массива для простого сита, потому что я пропустил все строки после этого и все еще столкнулся с проблемой. Я изначально объявлял массив, используя следующий код, который возвращал ошибку сегментации для значений до 10 миллионов.

int primesieve[a+1];

Я искал решение на этом сайте, которое дало изменение динамическому распределению массива, но в то время как это разрешило проблему на 10 миллионов, это, по-видимому, не для значительно больших значений. Другие решения, которые я заметил, упоминали что-то об использовании malloc() или объявлении массива статически вне main(), но, откровенно говоря, я не понимал, что это мой вводный класс программирования, который едва упоминался malloc(), и я думал, что код, предшествующий объявлению массива, который должен содержаться в main(). (Для справки: ошибка сегментации при создании больших массивов в C и Seg Fault при инициализации массива.) Я уверен, что это довольно простая проблема, но я относительно новый программист и, следовательно, плохо разбираюсь в распределении памяти, поэтому любое предложение, решение или объяснение других решений, которые я нашел, будет с благодарностью оценено.

Теги:
arrays

3 ответа

0
Лучший ответ

Ваш опыт связан с физическими ограничениями и точностью вашего компилятора. Первая попытка, выделяющая массив в стеке

int primesieve[a+1];

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

Выделение на кучу

int* primesieve = new int[a+1]; 

дает вам больше места, но у вас все еще есть предел адресной памяти. Теперь, 600851475143 - довольно большое число, даже если вы разделите его на 2. И если размер int равен 4 байтам, вы можете подумать, действительно ли вы можете решить эту большую память. С 32 битами вы можете адресовать 2 ^ 32 = 4294967296 байт.

0

Переполнение!

Он не может выделить размер массива 600851475143 в вашей памяти. В 32-битной системе требуется 4 4,476 GB.

0
600851475143 * sizeof(int64_t) = 4806811801144 = 4.4TB

Другими словами, этот код всегда будет сбой, если у вас нет 5 ТБ ОЗУ.

Вы можете сделать его более терпимым, если вы используете растровое изображение для вашего сита. Например, использование 1 бит на номер, а не отображение четных чисел, требует только 600851475143/8/2= 35GB ОЗУ. Еще много, но возможно, если у вас есть деньги на оборудование.

Ещё вопросы

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