2013-08-29 3 views
3

Я написал код для сита, но программа работает только для размера массива, меньшего или равного 1000000. Для остальных случаев, которые больше, происходит простое SIGSEGV. Может ли это быть сделано для запуска случаев> 1000000. Или где я ошибаюсь?Сито эратосфена: SIGSEGV?

#include <stdio.h> 
    int main() 
    { 
    unsigned long long int arr[10000001] = {[0 ... 10000000] = 0}; 
    unsigned long long int c=0,i,j,a,b; 
    scanf("%llu%llu",&a,&b); 
    for(i=2;i<=b;i++) 
     if(arr[i] == 0) 
      for(j=2*i;j<=b;j+=i) 
       arr[j] = 1; 
    for(i=(a>2)?a:2;i<=b;i++) 
    if(arr[i] == 0)`` 
     c++; 
    printf("%llu",c); 
    return 0; 
    } 
+2

Связанный: Вы понимаете (или взглядов его не), что данные * в * решето Эратосфена может быть в буквальном смысле * бит *, (используйте 'unsigned char', если вы не хотите делать математику с битовым смещением)? Думаю об этом. его массив * flags *, вот и все. Его * указывает * на тот массив, который вам действительно нужен. Существует * нет * причины хранения 64-битных значений, когда все, о чем вы заботитесь, это то, являются ли они нулевыми или ненулевыми. – WhozCraig

+4

Relax: SIGSEGV является последним премьер. –

+0

@WhozCraig Да, сэр, я это понял. Обычная глупость для хранения 0/1 в unsigned long long. – pukingminion

ответ

9

Эта строка выделяет память в стеке (который является ограниченным ресурсом)

unsigned long long int arr[10000001] = {[0 ... 10000000] = 0}; 

Если выделения 10000000 записи в 4 байта каждый, то есть 40 миллионов байт, который будет больше, чем ваш стек может ручка.

(или на вашей платформе, есть хороший шанс, что долго-долго-INT 8 или более байт, это означает 80 миллионов байт в использовании!)

Вместо выделения памяти из кучи, который является гораздо более многочисленны:

int* arr = malloc(10,000,000 * sizeof(int)); // commas for clarity only. Remove in real code! 

Или, если вы хотите, чтобы память инициализируется нулем, используйте calloc.

Затем в конце вашей программы убедитесь, что вы также бесплатно его:

free(arr); 

PS Синтаксис {[0 ... 10000000] = 0}; неоправданно многословным. Чтобы инициализировать массив в ноль, просто:

int arr[100] = {0}; // Thats all! 
+1

... или застревать в глобальной памяти за пределами 'main()'. Так или иначе. – WhozCraig

+2

Он может оставаться локальным, он просто не должен находиться в стеке. Добавление 'static' также исправит его. –

+3

@abelenky - это расширение GCC для установки диапазона массивов. http://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html#Designated-Inits В случае OP это может быть просто '{0}'. –

5

Вы объявили массив, который может содержать 10000001 элементов; если вы хотите обрабатывать большие числа, вам нужен больший массив. Я слегка удивлен, что он уже работает на 1000000 - это много пространства стека, которое нужно использовать.

Редактировать: извините - не заметил, что у вас было другое количество нулей. Не используйте стек для выделения массива, и все должно быть в порядке. Просто добавьте static в объявление массива, и вы, вероятно, будете в порядке.

Смежные вопросы