我正在学习C.对于学校作业,我写了一些代码来打印一定范围内的素数。我使用50000作为位数组的最大字节。我的代码编译,但它给我一个错误称为“分段错误:11”(它停在46337)。有人能告诉我代码中的问题是什么吗?我该如何解决这个错误?谢谢。
#include <stdio.h>
#include <stdlib.h>
//#define MAXBYTES 1000000
#define MAXBYTES 50000
void setBit(unsigned int A[], int k);
unsigned getBit(unsigned int A[], int k);
void print_prime (int prime_num);
void sieve_Prime(unsigned int bit_arr[]);
int main (int argc, char** argv)
{
//int bit_arr[MAXBYTES]; //This is the bit array (32 X MAXBYTES)
unsigned int bit_arr[MAXBYTES]; //or bit_arr[MAXBYTES]
int i;
for (i=0; i < MAXBYTES; i++)
{
bit_arr[i] = 0x00; //initialize all bits to 0s
}
setBit(bit_arr, 0); //0 is not prime, set it to be 1
setBit(bit_arr, 1); //1 is not prime, set it to be 1
sieve_Prime(bit_arr);
printf("\n");
return 0;
}
//Set the bit at the k-th position to 1
void setBit(unsigned int A[], int k)
{
int i = k/32;
int pos = k % 32;
unsigned int flag = 1; //flag = 0000 ..... 00001
flag = flag << pos; //flag = 0000...010...000 (shifted k positions)
A[i] = A[i] | flag; //Set the bit at the k-th position in A[i];
}
//get the bit at the k-th position
unsigned getBit(unsigned int A[], int k)
{
int i =k/32;
int pos = k % 32;
unsigned int flag = 1;
flag = flag << pos;
if (A[i] & flag)
return 1;
else
return 0;
}
void print_prime (int prime_num)
{
//print a prime number in next of 8 columns
static int numfound=0;
if (numfound % 8 == 0)
printf("\n");
if (prime_num+1 < MAXBYTES*8)
printf("%d\t", prime_num);
numfound++;
}
void sieve_Prime(unsigned int bit_arr[])
{
int i;
int k;
int next_prime = 2;
print_prime(2);
while (next_prime+1 < MAXBYTES*8)
{
k = next_prime;
//multiples of next_prime is not primpe
while(next_prime*k < MAXBYTES*8)
{
setBit(bit_arr, next_prime*k); //set it to be 1
k++;
}
//find next_prime by skipping non-prime bits marked 1
next_prime++;
while (next_prime + 1 < MAXBYTES*8 && getBit(bit_arr, next_prime))
{
next_prime++;
}
print_prime(next_prime);
}
}
答案 0 :(得分:3)
在while(next_prime*k < MAXBYTES*8)
next_prime*k
的最大值为(MAXBYTES*8-1)*(MAXBYTES*8-1)
。
这个较大的值无法保留在已签名的int
中,并且可能会变为负值,从而导致段错误。
使用
while(unsigned(next_prime*k) < MAXBYTES*8)
将消除段错误。
答案 1 :(得分:2)
首先要做的是决定MAXBYTES
实际意味着什么。由于您将数组bit_arr
分配给具有多个整数而不是字节,因此您需要分配所需内存的4倍并浪费它。此外,你将它作为一个本地分配在堆栈上 - 许多机器在堆栈上没有那么多空间,这可能是它失败的原因。最好将其设置为静态或使用malloc()
在堆上分配。
此外,您需要更加关注所用数字的范围:i
和k
,例如,可能最多MAXBYTES*8
,因此您可能需要制作他们long
如果你增加它。并且您的中间结果k * next_prime
可能会溢出int
。
就个人而言,由于你是按位索引数组,我会用相同的术语设置你的限制以使事情更清楚 - 有一个MAXBITS
,将数组分配为MAXBITS/32
,比较限制和以位为单位的范围,并确保您的位数适合变量类型。