2013-10-03 66 views
0

我做單鏈表的C程序中開發的C++ 其代碼如下:我的程序給分段錯誤

#include<stdio.h> 
typedef struct node 
{ 
    int data; 
    struct node *next; 
}node; 
node *insert(node*,int,int); 
node *create(int); 
node *del(node*,int); 
int print(node*); 
int main() 
{ 
    node *head; 
    int n,ch,n1,x,key,k; 
    head = NULL; 
    printf("\n Number of nodes:"); 
    scanf("%d",&n); 
    while(1) 
    { 
    printf("\nYour choices are:"); 
    printf("\n1) Create"); 
    printf("\n2) Print"); 
    printf("\n3) Insert"); 
    printf("\n4) Delete"); 
    printf("\n5) Reverse\n");   
    printf("Enter your choice:"); 
    scanf("%d",&ch); 
    switch(ch) 
    { 
    case 1:   
    head = create(n); 
    break; 

    case 2: 
    n1 = print(head); 
    break; 

    case 3: 
    printf("Enter the element to be inserted:"); 
    scanf("%d",&x); 
    printf("Enter the position where it is to be inserted:"); 
    scanf("%d",&key);  
    head = insert(head,x,key); 
    break; 

    case 4: 
    printf("Enter the element to be deleted:"); 
    scanf("%d",&k); 
    head = del(head,k); 
    break; 

    case 5: 
    break; 

    default: 
    exit(0); 
    break; 
    } 
    } 
    return(0); 
} 
node *create(int n) 
{ 
    node *head,*p; 
    int i; 
    printf("Enter %d data fields",n); 
    head = (node*)malloc(sizeof(node)); 
    head->next = NULL; 
    scanf("%d",&(head->data)); 
    p=head; 

    for(i=1;i<n;i++) 
    { 
      p->next = (node*)malloc(sizeof(node)); 
      p=p->next; 
      scanf("%d",&(p->data)); 
      p->next=NULL; 
    } 
    printf("Linked list created."); 
    return(head); 
} 
int print(node *p) 
{ 

    while(p!=NULL) 
    { 
      printf("%d-->",p->data); 
      p=p->next; 
    } 
    printf("NULL"); 
    return(0); 
} 
node *insert(node *head,int x,int key) 
{ 
    node *p,*q; 
    p = (node*)malloc(sizeof(node)); 
    p->data = x; 
    if(key==-1) 
    { 
     p->next = head; 
     head=p; 
    } 
    else 
    { 
     q = head; 
     while(key != q ->data && q!=NULL) 
      q=q->next; 
     if(q!=NULL) 
     { 
      p->next = q->next; 
      q->next = p; 
     } 
    } 
    printf("Element Inserted."); 
    return(head);  
}  
node *del(node *head,int x) 
{ 
    node *p,*q; 
    if(x == head->data) 
    { 
      p = head; 
      head = head->next; 
      free(p); 
    } 
    else 
    { 
     while(x != (p->next)->data && p->next != NULL) 
      p=p->next; 
     if(p->next != NULL) 
     { 
      q = p->next; 
      p->next = (p->next)->next; 
      free(q); 
     } 
    } 
    return(head); 
}  

一切順利,但是當我嘗試刪除一個節點時,控制檯只是崩潰,當我調試它顯示「訪問衝突錯誤:分段錯誤」 我的程序有什麼問題。

+0

在你的while循環中,看看'x!=(p-> next) - > data'。當它第一次碰到這個表達式時,是否已經設置了'p'? (提示:「否」)。 – lurker

+0

在'else'執行之前,你在'del()'中設置'p'的位置。 –

回答

1

指針p尚未在del(..)中的else塊之前初始化。

您不能訪問P->未來p是一個空指針。

+2

你怎麼知道這是一個空指針? – 2013-10-03 16:39:28

+0

你說得對,未初始化指針的值是不確定的。我不應該這樣做。 –

1

你的錯誤是在這裏

while(x != (p->next)->data && p->next != NULL). 

好像你正在嘗試讀取possiby空元素的下一個或數據您檢查前如果爲空,如果是空,這將導致賽格故障。

現在我開始使用調試器了。讓我告訴你用gdb發現這個錯誤是多麼簡單 - 我不會解釋到底是什麼即時消息,因爲這裏有幾百個GDB教程,但希望事實上,這需要我在15秒內找到你的錯誤將鼓勵你自己去谷歌,並通過這些教程:

eos% gcc -g test.c -o a 
test.c: In function ‘main’: 
test.c:56: warning: incompatible implicit declaration of built-in function ‘exit’ 
test.c: In function ‘create’: 
test.c:67: warning: incompatible implicit declaration of built-in function ‘malloc’ 
test.c: In function ‘insert’: 
test.c:96: warning: incompatible implicit declaration of built-in function ‘malloc’ 
test.c: In function ‘del’: 
test.c:124: warning: incompatible implicit declaration of built-in function ‘free’ 
test.c:134: warning: incompatible implicit declaration of built-in function ‘free’ 
eos% gdb a 
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1) 
Copyright (C) 2010 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-redhat-linux-gnu". 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>... 
Reading symbols from nonOfYourBussiness...done. 
(gdb) run 
Starting program: nonOfYourBussiness/a 

Number of nodes:5 

Your choices are: 
1) Create 
2) Print 
3) Insert 
4) Delete 
5) Reverse 
Enter your choice:1 
Enter 5 data fields1 2 3 4 5 
Linked list created. 
Your choices are: 
1) Create 
2) Print 
3) Insert 
4) Delete 
5) Reverse 
Enter your choice:4 
Enter the element to be deleted:3 

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000400a2b in del (head=0x602010, x=3) at test.c:128 
128    while(x != (p->next)->data && p->next != NULL) 
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6_4.4.x86_64 
(gdb) l 
123    head = head->next; 
124    free(p); 
125   } 
126   else 
127   { 
128    while(x != (p->next)->data && p->next != NULL) 
129     p=p->next; 
130    if(p->next != NULL) 
131    { 
132     q = p->next; 
(gdb) 
0

指針p未被初始化之前,它在del函數中訪問。

0

您的刪除函數中沒有初始化指針'p'。

只是這行添加到您的代碼: -

p = (node*)malloc(sizeof(node)); 

或者因爲你需要實現刪除功能,我想你需要點「P」於頭指針。 這樣做 -

p = head; 

希望這有助於。