2013-12-09 75 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->下一个){' –