2015-07-12 21 views
1

我有我的程序段故障求質數的數目達到N.故障(N> 10000)

我用素數動態鏈表測試N的效率。

問題是這樣的,當N < = 17508。它的N越大,特別是當我把打印結果加起來時,它總是有分段錯誤。誰能幫忙?謝謝。

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

typedef struct prime{ 
long value; 
struct prime *next; 
}prime; 

long numofprime(long n) 
{ 
long a, b, c; 

prime *head, *p1, *p2, *p3; 
int flag; 

if(n<0) 
n=-n; 

if(n<2) 
    return 0; 
else if(n==2) 
    return 1; 
else 
{/*creat linked list*/ 
    p1=(prime *)malloc(sizeof(prime)); 
    p1->value=2; 
    p1->next=NULL; 
    p2=p1; 
    head=p1; 

     b=1; 
     for(a=3;a<=n;a+=2) 
     { 
      flag=0; 
      p3=head; 
      while(p3!=NULL) 
      { 
       c=p3->value; 
       if(a%c==0) 
       { 
        flag=1; 
        break; 
       } 
       p3=p3->next; 
      } 

      if(flag==0) 
      {/*add prime number to the linked list*/ 
       p1=(prime *)malloc(sizeof(prime)); 
       p1->value=a; 
       p2->next=p1; 
       p2=p1; 
       b++; 
      } 
     } 

     c=0; 
     while(head!=NULL) 
     { 
      printf("%5ld ", head->value); 
      if(c%15==0) printf("\n"); 
      head=head->next; 
      c++; 
     } 

     return b; 
    } 

} 

int main(int argc, char *argv[]) 
{ 

long n; 
long np; 

if(argc<2) 
{ 
    printf("Please input the max num!\n"); 
    exit(0); 
} 
else if(argc>2) 
{ 
    printf("Too many arguments!\n"); 
    exit(0); 
} 
else 
    n=strtol(argv[1], NULL, 10); 

    np=numofprime(n); 

    printf("\n\nthere are %ld primes < n!\n", np); 

    return 0; 
} 
+0

當你在一個調試器中運行時,它說崩潰在哪裏?這個表達式中涉及的所有變量對您來說看起來都沒問題嗎? –

+1

請正確縮進您的代碼。 –

+0

它在long numofprime(long n)行處崩潰 { –

回答

3

當你分配的鏈表一個新項目,總是指向next項設置爲NULL。否則,無法檢測鏈表的結尾,出現未定義的行爲並且可能出現分段錯誤。

例如:

 {/*add prime number to the linked list*/ 
      p1=malloc(sizeof(prime)); 
      if(p1==NULL){fprintf(stderr,"failed to allocate\n");exit(1);} 
      p1->value=a; 
      p1->next=NULL; ///this new line here 
      p2->next=p1; 
      p2=p1; 
      b++; 
     } 

此外,不要在函數的末尾不忘free()內存。執行head=head->next來打印鏈表不會緩解此操作,因爲不可能返回:指向鏈接列表開頭的指針會丟失。始終保持指向某個鏈接列表開頭的指針!

+0

謝謝弗朗西斯,這個作品! –

+0

好點。這個代碼的時間複雜度是多少?(N(logN)?我對此沒有任何認識。 –

+0

在n之下有大約ln(n)的素數,所以操作的總數約爲\ sum_ {n = 1}^N ln(n))。這個總和大約是N.ln(N)-N。所以你的程序的複雜度是O(N.ln(N))。注意,你可以儘快地斷開while循環'p3-> value'在'sqrt(a)'上方,它不會改變複雜度,但它可能會將計算時間除以2。 – francis