2013-08-18 4 views
1

나는 C를 배우고있다. 학교 과제를 위해, 나는 특정 범위 내에서 소수를 인쇄하기위한 코드를 작성했다. 비트 배열의 경우 maxbyte로 50000을 사용합니다. 내 코드가 컴파일되지만 "segmentation fault : 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); 

    } 
} 
+2

오류가 발생한 줄은 무엇입니까? – Barmar

답변

3

while(next_prime*k < MAXBYTES*8)

next_prime*k에서 가장 큰 값 (MAXBYTES*8-1)*(MAXBYTES*8-1)이다. 이 큰 값은 부호가있는 int에 보관할 수 없으며 음수 값으로 바뀌어 segfault가 발생할 수 있습니다. 세그먼트 폴트를 제거 할

while(unsigned(next_prime*k) < MAXBYTES*8) 

를 사용

.

+0

아마 * 부호없는 값을 사용할 수 있습니다 *? – WhozCraig

+0

@ a.lasram : 팁 주셔서 감사합니다! – user2203774

+0

@ a.lasram : 질문이 하나 더 있습니다. MAXBYTES를 5000000으로 변경하면 작동하지 않습니다. 다시 동일한 분할 오류가 발생합니다. 왜 그런가요? 모든 것을 부호없는 int로 변경했습니다. – user2203774

2

먼저 할 일은 MAXBYTES이 실제로 의미하는 바를 생각해보십시오. bit_arr 배열에 바이트가 아닌 많은 정수가 할당되므로 필요한 메모리를 4 배 할당하고 낭비하게됩니다. 또한 스택에 로컬로 할당 할 수 있습니다. 많은 시스템에서 스택에 많은 공간이 없으므로 더 큰 수의 스택이 실패 할 수 있습니다. 정적으로 만들거나 malloc()으로 힙에 할당하는 것이 좋습니다.

는 또한, 사용되는 숫자의 범위에 대한 자세한 돌볼 필요 : 당신은 당신이 그것을 증가하면 그들에게 long을해야 할 수 있도록 ik는, 예를 들어, MAXBYTES*8까지 할 수있다. 그리고 오버플로 가능성이있는 k * next_prime 중간 결과가 int입니다. 당신이 비트에 의해 배열을 인덱싱하기 때문에

개인적으로, 나는 명확하게 일을하기 위해 그 같은 측면에서 한계를 설정합니다 - MAXBITS을 가지고 MAXBITS/32으로 배열을 할당, 한계를 비교하고 비트의 관점에서 범위 및 비트 수를 변수 유형에 맞춰야합니다.