【问题标题】:Sieve of Eratosthenes : SIGSEGV?埃拉托色尼筛:SIGSEGV?
【发布时间】:2013-08-29 21:02:52
【问题描述】:

我已经编写了筛子的代码,但程序仅针对小于或等于 1000000 的数组大小运行。对于其余较大的情况,会发生简单的 SIGSEGV。这可以运行案例 > 1000000。或者我错在哪里?

    #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;
    }

【问题讨论】:

  • 相关:您确实意识到(或从外观上看您不知道)数据in一个eratosthenes筛子实际上可以是bits,(如果您不想进行位偏移数学,请使用unsigned char)?想想看。它是一个 flags 数组,仅此而已。它是您真正关心的数组的indicies。当您只关心它们是零还是非零时,没有理由存储 64 位值。
  • 放松:SIGSEGV 是最后一个素数。
  • @WhozCraig 是的,先生,我意识到了。将 0/1 存储在 unsigned long long 中是愚蠢的。

标签: c


【解决方案1】:

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

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

如果您要分配 10,000,000 个条目,每个条目 4 个字节,那就是 4000 万字节,这将超出您的堆栈的处理能力。

(或者,在您的平台上,long-long-int 很有可能是 8 个或更多字节,表示正在使用 8000 万字节!)

相反,从堆中分配内存,这要丰富得多:

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!  

【讨论】:

  • ... 或将其卡在main() 之外的全局内存中。无论哪种方式。
  • 它可以保持在本地,它只需要不在堆栈上。添加static 也可以解决问题。
  • @abelenky - 这是用于设置数组范围的 GCC 扩展。 gcc.gnu.org/onlinedocs/gcc/… 在 OP 的情况下,它可能只是 { 0 }
  • @abelenky-非常感谢!语法{[0 .. } 将所有数组元素初始化为零。
【解决方案2】:

您声明了一个可以容纳 10000001 个项目的数组;如果要处理更大的数字,则需要更大的数组。我有点惊讶它已经适用于 1000000 - 这是需要使用的大量堆栈空间。

编辑:抱歉 - 没有注意到你那里有不同数量的零。不要使用堆栈来分配你的数组,你应该没问题。只需在数组声明中添加static 就可以了。

【讨论】:

    猜你喜欢
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    • 2016-10-29
    相关资源
    最近更新 更多