2013-12-09 102 views
0

我正在嘗試在C中爲一個類實現Sieve算法。我並沒有要求爲我完成這項任務。我已經寫出了我的函數,但我目前正在收到Segmentation Fault錯誤。我不是100%確定那是什麼。這是我的代碼到目前爲止,任何人都可以看到這個錯誤來自哪裏?在C中使用鏈接列表實現Eratosthenes的篩選(分段錯誤)

#define EXTERN 

#include <stdio.h> 
#include <stdlib.h> 
#include "header.h" 

void clearAll() { 
    int i, j; 
    seg *p; 
    p = head; 
    for(i = 0; i < NSegs; i++) { 
      p = p -> next; 
      for(j = 0; j < 256; j++) { 
        p -> bits[j] = 0; 
      } 
    } 
} 
int setBit(int n) { 
    int segment, index, hold, pos, i; 
    seg *p; 
    p = head; 

    segment = n/256; 
    hold = n; 
    while(hold > 65) { 
     hold = hold - 65; 
     index++; 
    } 
    pos = (hold - 1)/2; 

    for(i = 0; i < segment; i++) { 
     p = p -> next; 
     p->bits[index] = p->bits[index] | (1 << pos); 
    } 
} 

    int testBitIs0(int n) { 
    int segment, index, hold, pos, i, r; 
    seg *p; 
    p = head; 
    segment = n/256; 
    hold = n; 
    while(hold > 65) { 
     hold = hold - 65; 
     index++; 
    } 
    pos = (hold - 1)/2; 
    printf("%d, %d, %d ", segment, index, pos); 
    for(i = 0; i < segment; i++) { 
     p = p -> next; 
     r = p->bits[index] & (1 << pos); 
    } 
} 

void sieveOfE(int N) 
{ 
    int i, j, k; 


    k = 1; // Start with 2 to find all primes 

    while (k <= N) 
    { 
     for (i = k; i <= N; i++){ 
      if(i % 2 == 0) { 
       break; 
      } 
      if (testBitIs0(i)){ 
       break; 
      } 
     } 

     for (j = 2*i; j <= N; j = j + i){ 
      setBit(j); 
     } 
     k = i+1; 
    } 
} 

int countPrimes(int n){ 
    int count, i; 
    count = 0; 
    for(i = 0; i <= n; i++) { 
     if(testBitIs0(i)){ 
      count++; 
     } 
    } 
    return count; 
} 

int printPrimes(int n){ 
     int i; 
     for(i = 0; i <= n; i++) { 
      if(testBitIs0(i)){ 
       printf("%d ", i); 
      } 
     } 
     printf("\n\n"); 

} 

鏈接列表已在主文件和頭文件中正確初始化。初始化來自一個框架文件,不應該被編輯。但是每個鏈表節點都包含一個位數組和一個指向下一個節點的指針。

+2

分段錯誤是您嘗試讀取/寫入尚未初始化的指針(它不指向分配的內存)時可能失敗的錯誤之一。所以尋找(我不打算爲你調試)。 – SJuan76

+1

在相關說明中:分開您的疑慮。創建鏈接列表的代碼並檢查它是否有效。之後,在其上實施篩子。這樣,您可以更容易地檢查錯誤的位置,並且您可以發佈http://sscce.org,這將幫助您更輕鬆(也更可能)。 – SJuan76

+2

這段代碼有足夠的問題,很難確定問題出在哪裏。沒有特別的順序......你似乎試圖遍歷(例如)setBit()中的鏈表,但是你沒有爲鏈表中的項目分配任何內存。你有代碼試圖迭代鏈表中的項目,但是假設鏈表中有NSegs(這很奇怪,因爲如果你知道需要多長時間,你應該只使用一個數組)。 –

回答

5

給程序員一個段錯誤的修復程序,你會喂他一天。教授程序員使用調試器,他會養活一輩子。

如果你在調試器下運行你的程序,它會在導致它的代碼行上陷入段錯誤崩潰,你可以檢查調用堆棧。如果您使用調試器,則btbacktrace命令將顯示您的堆棧。

Here is a GDB turorial

正如註釋中指出的那樣,段錯誤通常發生在您嘗試取消引用無效指針時,無論是由於多種原因導致它未初始化,損壞或出錯。

+0

謝謝,我將與之合作! – Xonal

+0

我已經得到了這個問題到我clearAll()函數。這是讀取'p-> bits [j] = 0;'的行。你會碰巧知道如何正確地清理陣列嗎? – Xonal

+0

@Xonal - 'p'是一個指針,所以幾乎可以肯定它是對是不正確這裏。用gdb中的print p來檢查。看着你的循環在你的代碼走列表點,你應該檢查,看看如果P不是取消引用前NULL。你可以爲聲明更改爲類似'爲(P =頭; P!= NULL; P = P->下一個){' –