数组大小错误
error with array size
我正在尝试制作一个程序,使用 Eratosthenes 筛法计算不超过整数的素数数量。虽然我的程序对于小数字运行良好(并且快速),但在一定数字 (46337) 之后我得到一个 "command terminated by signal 11" 错误,我认为这与数组大小有关。我尝试使用 malloc() 但我没有完全正确。对于大数字(最多 50 亿)我该怎么办?
#include <stdio.h>
#include<stdlib.h>
int main(){
signed long int x,i, j, prime = 0;
scanf("%ld", &x);
int num[x];
for(i=2; i<=x;i++){
num[i]=1;
}
for(i=2; i<=x;i++){
if(num[i] == 1){
for(j=i*i; j<=x; j = j + i){
num[j] = 0;
}
//printf("num[%d]\n", i);
prime++;
}
}
printf("%ld", prime);
return 0;
}
你的数组
int num[x];
在栈上,这里只能容纳小数组。对于大数组大小,您必须分配内存。您可以使用 char
类型来节省内存膨胀,因为您只需要一个状态。
char *num = malloc(x+1); // allow for indexing by [x]
if(num == NULL) {
// deal with allocation error
}
//... the sieve code
free(num);
我还建议,您必须使用
检查 i*i
没有打破 int
限制
if(num[i] == 1){
if (x / i >= i){ // make sure i*i won't break
for(j=i*i; j<=x; j = j + i){
num[j] = 0;
}
}
}
最后,您想达到 50 亿,这超出了 uint32_t
的范围(unsigned long int
在我的系统上)42 亿。如果这会让您满意,请将 int
定义更改为 unsigned
,注意您的循环控件不要换行,即使用 unsigned x = UINT_MAX - 1;
如果您没有 5Gb 内存可用,请按照@BoPersson 的建议使用位状态。
以下代码检查错误,使用最大 5000000000 的值进行测试,正确输出素数的最终计数,使用 malloc 以避免溢出可用堆栈 space。
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long int x,i, j;
unsigned prime = 0;
scanf("%lu", &x);
char *num = malloc( x);
if( NULL == num)
{
perror( "malloc failed");
exit(EXIT_FAILURE);
}
for(i=0; i<x;i++)
{
num[i]=1;
}
for(i=2; i<x;i++)
{
if(num[i] == 1)
{
for(j=i*i; j<x; j = j + i)
{
num[j] = 0;
}
//printf("num[%lu]\n", i);
prime++;
}
}
printf("%u\n", prime);
return 0;
}
我正在尝试制作一个程序,使用 Eratosthenes 筛法计算不超过整数的素数数量。虽然我的程序对于小数字运行良好(并且快速),但在一定数字 (46337) 之后我得到一个 "command terminated by signal 11" 错误,我认为这与数组大小有关。我尝试使用 malloc() 但我没有完全正确。对于大数字(最多 50 亿)我该怎么办?
#include <stdio.h>
#include<stdlib.h>
int main(){
signed long int x,i, j, prime = 0;
scanf("%ld", &x);
int num[x];
for(i=2; i<=x;i++){
num[i]=1;
}
for(i=2; i<=x;i++){
if(num[i] == 1){
for(j=i*i; j<=x; j = j + i){
num[j] = 0;
}
//printf("num[%d]\n", i);
prime++;
}
}
printf("%ld", prime);
return 0;
}
你的数组
int num[x];
在栈上,这里只能容纳小数组。对于大数组大小,您必须分配内存。您可以使用 char
类型来节省内存膨胀,因为您只需要一个状态。
char *num = malloc(x+1); // allow for indexing by [x]
if(num == NULL) {
// deal with allocation error
}
//... the sieve code
free(num);
我还建议,您必须使用
检查i*i
没有打破 int
限制
if(num[i] == 1){
if (x / i >= i){ // make sure i*i won't break
for(j=i*i; j<=x; j = j + i){
num[j] = 0;
}
}
}
最后,您想达到 50 亿,这超出了 uint32_t
的范围(unsigned long int
在我的系统上)42 亿。如果这会让您满意,请将 int
定义更改为 unsigned
,注意您的循环控件不要换行,即使用 unsigned x = UINT_MAX - 1;
如果您没有 5Gb 内存可用,请按照@BoPersson 的建议使用位状态。
以下代码检查错误,使用最大 5000000000 的值进行测试,正确输出素数的最终计数,使用 malloc 以避免溢出可用堆栈 space。
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long int x,i, j;
unsigned prime = 0;
scanf("%lu", &x);
char *num = malloc( x);
if( NULL == num)
{
perror( "malloc failed");
exit(EXIT_FAILURE);
}
for(i=0; i<x;i++)
{
num[i]=1;
}
for(i=2; i<x;i++)
{
if(num[i] == 1)
{
for(j=i*i; j<x; j = j + i)
{
num[j] = 0;
}
//printf("num[%lu]\n", i);
prime++;
}
}
printf("%u\n", prime);
return 0;
}