2017-02-28 3 views
0

Probieren Sie Fedora gcc den folgenden Code für eine einfache Linked List Hinzufügen neuer Knoten zum Ende der Liste. Kein Fehler beim Kompilieren. Während der Ausführung wird Segmentierungsfehler, Core Dumped angezeigt. Unter MS Windows funktioniert es.Linked List-Fehler "Segmentierungsfehler" Core Dumped

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

struct Node 
{ 
    int data; 
    struct Node *next; 
}; 

void insertion(struct Node *); 
void display(struct Node *); 

int main(void) 
{ 
    struct Node *head; 
    head=NULL; 
    head->next=NULL; 

    int choice, cont; 

    do 
    { 
     printf("1.Insert  2.Display  3.Exit"); 
     scanf("%d",&choice); 

     if(choice==1) 
     { 
      insertion(head); 
     } 
     else if(choice==2) 
     { 
      display(head); 
     } 
     else if(choice==3) 
     { 
      exit(0); 
     } 
     else 
     { 
      printf("Wrong choice"); 
     } 
     printf("Continue? Press 1 otherwise 0:"); 
     scanf("%d",&cont); 
    }while(cont==1); 

    return 0; 
} 

void insertion(struct Node *start) 
{ 
    int data; 
    struct Node *temp=NULL; 
    temp->next=NULL; 
    struct Node *mnew=NULL; 
    mnew->next=NULL; 

    mnew=(struct Node *)malloc(sizeof(struct Node)); 

    printf("Enter data:"); 
    scanf("%d",&data); 

    mnew->data=data; 

    if(start==NULL) 
    { 
     start=mnew; 
    } 
    else if(start!=NULL && start->next==NULL) 
    { 
     start->next=mnew; 
    } 
    else 
    { 
     temp=start; 
     while(temp->next!=NULL) 
     { 
      temp=temp->next; 
     } 
     temp->next=mnew; 
    } 
} 

void display(struct Node *start) 
{ 
    struct Node *temp=NULL; 
    temp->next=NULL;  
    if(start==NULL) 
    { 
     printf("\nNothing to display!"); 
    } 
    else if(start!=NULL && start->next==NULL) 
    { 
     printf("%d",start->data); 
    } 
    else 
    { 
     temp=start; 
     while(temp!=NULL) 
     { 
      printf("%d",temp->data); 
      temp=temp->next; 
     } 
    } 
} 

Ihre Hilfe wird geschätzt.

+1

Zeit zu lernen, wie man einen Debugger verwenden. –

+0

Außerdem 'start = mneu;' ändert nicht 'Haupt'-Hauptwert ..... Sie sollten etwas über Zeiger studieren. – LPs

Antwort

2

Betrachten Sie z.B. Diese zwei Zeilen von der insertion Funktion:

struct Node *temp=NULL; 
temp->next=NULL; 

Die erste definiert einen Zeiger auf struct Node und macht es zu einem Nullzeiger sein. In der nächsten Zeile dereferenzieren Sie diesen Nullzeiger, der ungültig ist und zu undefiniertem Verhalten führt.

Sie haben das gleiche Problem an mehreren Stellen, beide genau so, und Null-Zeiger im Allgemeinen auch denerenzieren.

+0

... oder OP kann 'calloc' anstelle von' malloc' verwenden – LPs

+0

Außerdem 'start = mneu;' ändert nicht 'head' Hauptwert – LPs

+0

@LPs - Wenn Sie' calloc' als eine Verknüpfung vorschlagen, um alle Zeiger zu setzen in der Struktur zu NULL, wissen, dass ein Null-Bit-Muster nicht garantiert ist, der Wert eines Null-Zeigers zu sein. [Siehe diese Standardnote zu "Calloc"] (http://port70.net/~nsz/c/c11/n1570.html#note296) als Referenz. – StoryTeller

5
head=NULL; 
head->next=NULL; 

Dieses Stück Code konnte nie funktionieren, wie Sie nicht oder Werte zuweisen Attribute head zugreifen können, wenn sie auf NULL (aka nirgends) zeigen wird.

+0

Ich habe diese zweiten Zeilen kommentiert und jetzt wird ausgeführt. Nach dem Einfügen von 3 Knoten meldet die Anzeigefunktion "Nichts anzeigen!" das bedeutet, der Start ist immer noch NULL. –

+0

Das liegt daran, dass Sie 'head' nicht aktualisieren - Sie müssen es entweder als Referenz in Ihre Einfügefunktion übergeben oder diese Funktion den neuen Start zurückgeben lassen, damit Sie es 'head' zuweisen können. –

+0

Außerdem' start = mneu; 'ändert nicht' Kopf' Hauptwert – LPs

1

Sie können nicht mit einem Nullzeiger auf Daten zugreifen. Daher ist dieser Code-Schnipsel (und ähnliche Code-Schnipsel)

struct Node *head; 
head=NULL; 
head->next=NULL; 
^^^^^^^^^^^^^^^ 

ist ungültig.

Wie für die Funktion insertion müssen Sie den Kopf als Referenz übergeben. Andernfalls wird die Funktion eine Kopie des Kopfes bearbeiten und Änderungen der Kopie des Kopfes in der Funktion haben keinen Einfluss auf den ursprünglichen Kopf.

Auch wenn die Speicherzuordnung fehlschlägt, ist es wünschenswert, dass die Funktion darüber signalisiert. Anstelle des Rückgabetyps void ist es besser, den Rückgabetyp int zu verwenden.

So kann die Funktionsdeklaration aussehen

int insertion(struct Node **); 
^^^   ^^^^^^^^^^^^^^ 

Die Funktion kann wie

int insertion(struct Node **start) 
{ 
    int data; 

    printf("Enter data: "); 
    scanf("%d", &data); 

    struct Node *temp = (struct Node *)malloc(sizeof(struct Node)); 

    int success = temp != NULL; 

    if (success) 
    { 
     temp->data = data; 
     temp->next = NULL; 

     while (*start) start = &(*start)->next; 

     *start = temp; 
    } 

    return success; 
} 

Die Funktion namens

insertion(&head); 

Die Funktion display kann die folgende Art und Weise können definiert werden aussehen wie

void display(struct Node *start) 
{ 
    if (start == NULL) 
    { 
     printf("\nNothing to display!\n"); 
    } 
    else 
    { 
     for (; start; start = start->next) 
     { 
      printf("%d ", start->data); 
     } 
     putchar('\n'); 
    } 
} 
+0

Ich bin überrascht, warum das sogar unter Windows funktioniert? Auch jeder vernünftige Compiler sollte in der Lage sein, dies zu erfassen und eine Warnung zu präsentieren. –

0

Als vorherigen Kommentar, eine NULL Zeiger auf einen anderen NULL Lenken nicht definiert ist (einen Zeiger verursachen sollte eine Adresse halten). nun einige Vorschläge:

1) definieren die Struktur wie folgt:

typedef struct Node *node_pointer; 

dies macht es einfacher Zeiger für diese Struktur zu definieren.

2)

mnew=malloc(sizeof(*mnew)); //this is easier, and this should be before the ..->next=NULL; 

auch überprüfen, ob Zuordnung erfolgreich:

if (!mnew) 
    return; //return something needed 
Verwandte Themen