C 中的这段代码决定一个数字是不是是素数,它会因大数而崩溃。为啥?

Posted

技术标签:

【中文标题】C 中的这段代码决定一个数字是不是是素数,它会因大数而崩溃。为啥?【英文标题】:This code in C which decides if a number is a prime number crashes with large numbers. Why?C 中的这段代码决定一个数字是否是素数,它会因大数而崩溃。为什么? 【发布时间】:2022-01-22 12:06:45 【问题描述】:

这就是代码,它在 4-5 位之前都可以正常工作。

int main()

int x;
printf("Enter a number: ");
scanf("%d", &x);
double list[x];
int i;
for(i=0;i<x;i++)
   list[ i ] = i+1;


double z;
int q;
double list2[x];
for(q=0;q<x;q++)
    z=x/list[q];
    if (z == floor(z))
    list2[q] = z;
    
    else 
        list2[q] = 0;
    

printf("\n--------------\n");
int n;
double nulla = 0.00000000;
int zero = 0;
for(n = 0; n < x; n++)

    if (fabs(list2[n]-0.00)==0.00)
        zero++;
    


if(zero == x-2)
printf("It is a prime number");
 
else
    printf("It is not a prime number");

printf("\n--------------\n");

return 0;

但是如果我输入例如 987521。它只会给出这个消息:Process returned -1073741571 (0xC00000FD),我一直在想也许一个数组不能存储这么大的数据,但也许我错了。有什么想法吗?

【问题讨论】:

您的数组double list[x];list2[x] 可能溢出了堆栈。 一个好的经验法则是堆栈只有 1MB。所以任何大于 1MB 的数组都不能在堆栈上。 double 通常是 8 个字节,所以 987521 个双精度数组大约是 8MB,这太大了。 我用double *list = malloc(x * sizeof(double)); 替换了double list[x];,同样替换了list2,并且程序“工作”了987521(也是987523)。但这不是测试素数的一种非常有效的方法! (我也很幸运:malloc 没有失败。通常测试这一点很重要。) 素数不溶于浮点数。 @SteveSummit 谢谢!我知道这可能不是最有效的方法,但这是我的第一个程序,我只是想做点什么,你能举一个更好的方法的例子吗? 【参考方案1】:

而不是像在行中那样在堆栈上分配内存

double list[x];

使用动态分配,比如

double* list = malloc(x * sizeof(double));

那么,在程序结束之前,别忘了解除分配:

free(list);

原因是堆栈分配的大小通常非常有限(MB 的顺序),一旦分配超过该限制,就会溢出堆栈。另一方面,动态内存(堆)受到操作系统的限制,并且通常可能非常大(受操作系统或物理+虚拟内存总量的限制)。

【讨论】:

Opinions differ 是“别忘了”还是“如果你真的想,你可以”。 (即解除分配。) @SteveSummit True :) 但这是一个好习惯,尤其是当你在程序中间mallocfree...

以上是关于C 中的这段代码决定一个数字是不是是素数,它会因大数而崩溃。为啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何用C语言判断一个数是不是为递增数

在使用列表推导生成素数时使用`all()`函数

用 C 语言编写一个程序,该程序使用递归来确定一个数字是不是为素数。大量出现堆栈溢出错误

求C语言中 判断素数的 代码!!!!!

C语言 设计并实现一种大素数随机生成方法; 实现一种快速判定任意一个大数是不是是素数方法 跪求啊

查询执行时间是不是因大表的不同查询参数值而异?