2012-03-06 49 views
4

我最近开始学习C语言。我用MinGW和Cygwin GCC使用Code :: Blocks。C中的“状态堆栈溢出”,使用简单迭代

我为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; 
} 
+0

试着设置一个更高的'ulimit'。在栈上分配550000个整数可能会导致这种情况。 – Benoit 2012-03-06 17:34:16

回答

4

好像你不能在堆栈上分配550000个整数,而是动态地分配它们。

int * sieve; 
sieve = malloc(sizeof(int) * (LIMIT+1)); 
+1

对于短期解决方案,您还可以调整编译器设置。不是一个好主意,如果你有一天醒来,并说你需要55000000而不是550000. – vsz 2012-03-06 17:35:56

1

该程序中的所有内存都分配在堆栈上。当增加数组的大小时,可以增加堆栈上所需的空间量。最终该方法不能被调用,因为堆栈上没有足够的空间来容纳它。

要么与malloc阵列(所以它被分配在堆上)的经验。或者学习如何告诉编译器分配一个更大的堆栈。

3

你的基本选项是存储变量在data segment当你的存储器块是比堆更大:

  • malloc在堆阵列分配存储器(如@Binyamin解释)
  • 存储在数据阵列/ BSS段通过声明数组为static int sieve[SIZE_MACRO]
+2

+1对于关于静态的评论。请注意,这意味着您的代码不再可重入,并且初始化程序只会被调用一次 - 对于名为main()的函数而言,这两者通常都不是问题。 – 2012-03-06 18:35:38