2013-08-29 71 views
3

我已经编写了筛网的代码,但程序仅运行数组大小小于或等于1000000的数据。对于其他较大的情况,会出现一个简单的SIGSEGV。这可以使运行情况> 1000000.或我错在哪里?Eratosthenes的筛子: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')?想想看。它的a * flags *数组,这就是所有。它对你真正关心的数组有*指示。当你所关心的是它们是零还是非零时,存在*没有理由存储64位值。 – WhozCraig

+4

放松:SIGSEGV是最后一个素数。 –

+0

@WhozCraig是的,先生,我意识到了。简单的愚蠢将0/1存储在无符号long long中。 – pukingminion

回答

9

此行分配内存在栈上(这是一种有限的资源)

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

如果你在每4个字节分配10,000,000项,即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添加到数组声明中,您可能会没事。