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 :) 但这是一个好习惯,尤其是当你在程序中间malloc
和free
...以上是关于C 中的这段代码决定一个数字是不是是素数,它会因大数而崩溃。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
用 C 语言编写一个程序,该程序使用递归来确定一个数字是不是为素数。大量出现堆栈溢出错误