2016-05-06 4 views
0

Ich versuche, zwei bereits sortierte verknüpfte Listen temp1 und temp2 zusammenzuführen. Ich erhalte Segmentierungsfehler für dieses Beispiel:segmentation fault (core dumped) Fehler erhalten Drucke vor der Ausführung von 'printf' Anweisungen

Eingang

temp1 : 1->NULL 

temp2 : 2->3->4->5->6->NULL 

Ausgabe

1st Output

aber wenn ich entfernen "\ n" von printf Aussagen dann direkt Segmentierungsfehler druckt.

2nd Output

Warum geschieht das?

Code:

list *merge(list * temp1, list * temp2) 
{ 
    list *x, *y, *z; 

    x = temp1; 
    y = temp2; 
    print(x); 
    print(y); 

    z = (list *) malloc(sizeof(list)); 

    if (x->key < y->key) 
    { 
     z->key = temp1->key; 
     x = x->next; 
    } 
    else 
    { 
     z->key = temp2->key; 
     y = y->next; 
    } 
    z->next = NULL; 

    while (x || y) 
    { 
     printf("asdf\n"); 
     if (x == NULL) 
     { 
      z = append(z, y->key); 
      y = y->next; 
      printf("x\n"); 
     } 
     if (y == NULL) 
     { 
      z = append(z, x->key); 
      x = x->next; 
      printf("y\n"); 
     } 
     if (x && y) 
     { 
      printf("x && y\n"); 
      if (x->key < y->key) 
      { 
       z = append(z, x->key); 
       x = x->next; 
      } 
      else 
      { 
       z = append(z, y->key); 
       y = y->next; 
      } 
     } 
    } 
    print(z); 
    return z; 
} 

Vielen Dank im Voraus.

Ich habe den Segmentierungsfehler bereits entfernt. Ich frage, warum es verzögert wird, wenn ich das '\ n' von printf-Aussagen entferne?

+1

Willkommen bei Stack-Überlauf! Es klingt, als müssten Sie lernen, wie Sie einen Debugger verwenden, um durch Ihren Code zu gehen. Mit einem guten Debugger können Sie Ihr Programm Zeile für Zeile ausführen und sehen, wo es von dem, was Sie erwarten, abweicht. Dies ist ein essentielles Werkzeug, wenn Sie programmieren wollen. Weiterführende Literatur: [Wie kleine Programme zu debuggen] (http://ericlippert.com/2014/03/05/how-to-debug-small-programs/). –

+1

Fragen Sie, warum Sie einen segfault erhalten oder warum Sie die Ausgabe nicht sehen, wenn Sie die Zeilenumbrüche entfernen? – Kevin

+1

Haben Sie versucht, einen Debugger zu verwenden? Sie ordnen entweder einen Zeiger nicht richtig zu oder überschreiben unerwünschten Speicher irgendwo, vielleicht sogar innerhalb von "append", was nicht angezeigt wird. Sie sollten dies eingrenzen, anstatt zu erwarten, dass andere hier Ihren gesamten Code durchforsten, um ihn zu finden. Auch, [werfen Sie nicht die Rückkehr von 'malloc'] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – lurker

Antwort

4

Der Grund, dass Sie Segmentierungsfehler erhalten, bevor Sie eine Ausgabe von printf sehen, ist, dass printf normalerweise auf stdout geleert wird, wenn Sie fflush(stdout) tun, oder wenn Sie \n hinzufügen, um ein Ende der Linie zu erhalten. Wenn Sie einen Segmentierungsfehler erhalten, bevor stdout geleert wurde, wird nichts in stdout verloren gehen.

3

Die Antwort von Henrik ist direkt auf den Punkt der Frage.

Dennoch gab es ein paar Kommentare zum OP, die die Verwendung des Debuggers vorschlugen. Hier ist, was Sie bekommen würden, wenn Sie fortfahren würden, durch den Code zu gehen.

Betrachten Sie den folgenden Code am Anfang des Körpers der while Schleife.

if(x == NULL){ 
    z = append(z,y->key); 
    y = y->next; 
    printf("x\n"); 
} 
if(y == NULL){ 
    z = append(z,x->key); 
    x = x->next; 
    printf("y\n"); 
} 

Lassen Sie uns Schritt für Schritt durch sie kurz vor dem segfault auftritt, ist, dass, wenn

x: NULL 
y: 6-> NULL 

Die x == NULL Bedingung erfüllt ist, daher fallen wir durch und führen

y = y-> next 

bekommen

x: NULL 
y: NULL 
Nun

die y == NULL Bedingung ist auch wahr, deshalb müssen wir

z = append(z,x->key) 

dereferencing den NULL-Zeiger x auszuführen. Voila, es ist ein Segfault.

Es ist nicht schwer, diesen Code zu korrigieren.

+0

Eigentlich habe ich gefragt, warum seg Fehler wird verzögert, wenn ich '\ n' entfernt. Aber Danke für deine Antwort – a0n1i2k3

2

Henrik erklärte sehr gut die Diskrepanzen zwischen dem Display und dem segfault.

Das eigentliche Problem

Aber ich nehme an, dass Sie in der Ursache Ihrer Segmentierungsfehler interessiert sind. In Ihrer while (x||y) Schleife haben Sie 3 verschiedene Fälle vorgesehen, die sich gegenseitig ausschließen zu sein scheinen:

  • if (x==NULL)
  • if (y==NULL)
  • if (x && y)

In der Tat ist das alles sehr logisch und es sollte funktionieren perfekt. Sie haben jedoch vergessen, dass es den Körper von jedem if Sie x oder y ändern.

Wenn Sie also das Ende der ersten Liste erreicht haben (zB x==NULL), gehen Sie zum nächsten Element der zweiten Liste, aber wenn Sie gerade das Ende der zweiten Liste erreicht haben, " lle execute if(y==NULL) und verschieben VERGANGEN DAS ENDE DER ERSTEN LISTE !! Das ist die Ursache für Ihren Segmentierungsfehler. Sie dereferenzieren einen Zeiger NULL.

Die einfache Lösung

Verwenden Sie einfach else:

if (x==NULL) 
    ... 
else if (y==NULL) 
    ... 
else if (x && y) 
    ...