0

私は Dev 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);  
}    

すべてうまくいきましたが、ノードを削除しようとするとコンソールがクラッシュし、デバッグすると「アクセス違反エラー: セグメンテーション違反」と表示されます。

4

4 に答える 4

1

あなたのエラーはここにあります

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

null であるかどうかを確認する前に、可能な null 要素の次のデータまたはデータを読み取ろうとしているようです。null の場合、セグ フォールトが発生します。

これで、デバッガーを使用することの素晴らしさを実感できます。gdb でそのエラーを見つけるのがいかに簡単であったかをお見せしましょう。文字通り何百もの GDB チュートリアルがあるので、私が何をしているのか正確には説明しませんが、エラーを見つけるのに 15 秒未満かかったという事実を願っています。 Google にアクセスして、これらのチュートリアルを自分で実行することをお勧めします!:

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)
于 2013-10-03T16:31:02.410 に答える
1

ポインターpは、del(..) の else ブロックの前に初期化されていません。

pが null ポインターの場合、p->nextにアクセスできません。

于 2013-10-03T16:26:36.687 に答える
0

ポインター p は、del 関数でアクセスされる前に初期化されません。

于 2013-10-03T17:04:31.480 に答える