«Переполнение стека состояний» в C с простой итерацией - PullRequest
4 голосов
/ 06 марта 2012

Я начал изучать C недавно. Я использую Code :: Blocks с MinGW и Cygwin GCC.

Я сделал очень простое простое сито для задачи Project Euler 10, которое печатает простые числа ниже определенного предела для стандартного вывода. Он работает нормально примерно до 500000 в качестве лимита, но выше этого мой скомпилированный minGW .exe падает, а скомпилированный GCC генерирует исключение "STATUS_STACK_OVERFLOW".

Я озадачен, почему, поскольку код полностью не рекурсивный и состоит из простых циклов for.

#include <stdio.h>
#include <math.h>
#define LIMIT 550000

int main()
{
    int sieve[LIMIT+1] = {0};
    int i, n;

    for (i = 2; i <= (int)floor(sqrt(LIMIT)); i++){
        if (!sieve[i]){
            printf("%d\n", i);
            for (n = 2; n <= LIMIT/i; n++){
                sieve[n*i] = 1;
            }
        }
    }
    for (i; i <= LIMIT; i++){
        if (!sieve[i]){
            printf("%d\n", i);
        }
    }
    return 0;
}

Ответы [ 3 ]

4 голосов
/ 06 марта 2012

Похоже, вы не можете выделить 550000 дюймов в стеке, вместо этого выделите их динамически.

int * sieve;
sieve = malloc(sizeof(int) * (LIMIT+1));
3 голосов
/ 06 марта 2012

Ваши основные опции - хранить переменные в сегменте данных , когда объем памяти превышает размер стека:

  • выделение памяти для массива в куче с malloc (как объяснил @Binyamin)
  • сохранение массива в сегментах данных / BSS, объявив массив как static int sieve[SIZE_MACRO]
1 голос
/ 06 марта 2012

Вся память в этой программе выделена в стеке. Увеличивая размер массива, вы увеличиваете объем пространства, требуемого в стеке. В конце концов, метод не может быть вызван, так как в стеке недостаточно места для его размещения.

Либо экспериментируйте с malloc в массиве (поэтому он расположен в куче). Или научитесь указывать компилятору выделять больший стек.

...