Fehler in Stackimplementierung
-
Hallo!
Ich bin gerade dabei, ein Problem nach dem "Die Türme von Hanoi" Schema zu lösen. Es gibt dabei drei Stäbe A, B, C (in meinem Programm sind das die Stapel a, b, c). Anfangs werden n Stäbe auf A abgelegt. Sie werden nach den zwei Regeln hin- und hergeschoben:
(*) Lege die oberste Scheibe von A auf B
(**) Lege die oberste Scheibe von B auf C
Diese Regeln sollen immer wieder nacheinander angewandt werden. Dazu habe ich den folgenden Algorithmus geschrieben ..#include <stdio.h> #include <stdlib.h> struct item { struct item *next; int value; }; struct stack { struct item *top; }; void stck_destroy(struct stack *stck) { int value; while( stck_pop(stck, &value) == 0 ) ; free( stck); } struct stack *stck_create() { struct stack *stck; stck = (struct stack *)malloc( sizeof( struct stack)); if( stck == NULL ) { return(0); } else { stck->top = 0; return stck; } } int stck_push(struct stack *stck, int val) { struct item *item; item = (struct item *)malloc( sizeof( struct item)); if( stck == NULL ) { return(-1); } else { item->value = val; item->next = stck->top; stck->top = item; return(0); } } int stck_pop(struct stack *stck, int *val) { struct item *item; item = stck->top; if( stck == NULL ) { return(-1); } else { *val = item->value; stck->top = item->next; free(item); return(0); } } int main() { printf("\n"); printf("\t Scheibenanordnungen\n"); printf("\t=====================\n\n"); printf("\tWieviele Scheiben n sollen\n"); printf("\tauf den Stapel \"a\" gelegt werden? "); int n; scanf("%d", &n); printf("\n"); // Erzeuge die Stapel "a", "b" und "c". struct stack *a, *b, *c; a = stck_create(); b = stck_create(); c = stck_create(); // Lege die Werte 1,2,3..n auf den Stapel "a" int i; for(i=1; i<=n; i++) { if( stck_push(a, i) == 0 ) { // Wert i wurde erfolgreich auf den Stapel "a" gelegt. printf("\t\"%d\" auf den Stapel \"a\" gelegt.\n", i); } else { // // Beende das Programm mit einem Errorcode, // da stck_push fehlschgeschlagen ist. // printf("\t\"%d\" konnte nicht auf den Stapel \"a\" gelegt werden.\n" ,i); printf("\tDas Programm wird beendet.\n\n"); return(-1); } } // // Speichere die heruntergenommenen Werte der // Scheiben in "scheibe1", "scheibe2", "scheibe3" // int scheibe1, scheibe2, scheibe3; // // Nach Definition gibt es folgende Regeln: // (*) Lege oberste Scheibe von "a" auf "b". // (**) Lege oberste Scheibe von "b" auf "c". // Die Regeln werden 2n mal angewandt. // while( stck_pop(a, &scheibe1) == 0 ) stck_push(b, scheibe1); while( stck_pop(b, &scheibe2) == 0 ) stck_push(c, scheibe2); printf("\t Ausgabe der Stapel \"a\", \"b\", \"c\"\n"); printf("\t==================================\n\n"); // Speichere die Rueckgabewerte der Funktion stck_pop getrennt fuer jeden Stapel int pop_a = stck_pop(a, &scheibe1); int pop_b = stck_pop(b, &scheibe2); int pop_c = stck_pop(c, &scheibe3); // Wiederhole dies solange, wie wenigstens von einem der Stapel etwas heruntergenommen werden kann printf("\t+------------+------------+------------+\n"); printf("\t| | | |\n"); printf("\t| Stapel \"a\" | Stapel \"b\" | Stapel \"c\" |\n"); printf("\t| | | |\n"); printf("\t+------------+------------+------------+\n"); printf("\t| | | |\n"); while( (pop_a == 0) || (pop_b == 0) || (pop_c == 0) ) { if( pop_a == 0 ) printf("\t| %10d ", scheibe1); else printf("\t| ", scheibe1); if( pop_b == 0 ) printf("| %10d ", scheibe2); else printf("| ", scheibe2); if( pop_c == 0 ) printf("| %10d |", scheibe3); else printf("| |", scheibe3); pop_a = stck_pop(a, &scheibe1); pop_b = stck_pop(b, &scheibe2); pop_c = stck_pop(c, &scheibe3); } printf("\t| | | |\n"); printf("\t+------------+------------+------------+\n"); stck_destroy(a); stck_destroy(b); stck_destroy(c); }
Bevor das Programm in Zeile 136 die einzelnen Stapel/Türme anzeigt, stürzt es mit "segmentation fault" ab
Was habe ich falsch gemacht?
Danke im Voraus!
-
Hallo.
Ein Seg-Fault kommt meistens, wenn du irgendwo mit einem Pointer hantierst, wo du es nicht solltest.Am besten, du baust dir einige printf()'s ein, um erstmal einzugrenzen, an welchen Stelle sich der Code verabschiedet. Damit kannst du das Problem ziemlich gut analysieren, weil du genau weißt, welche Anweisung noch ausgeführt wird.
Versuch das erstmal.
-
int stck_pop(struct stack *stck, int *val) { struct item *item; item = stck->top; if( stck == NULL ) { return(-1); } else { // Hier raucht das Programm ab *val = item->value; stck->top = item->next; free(item); return(0); } }
Oben im Code siehst du, an welcher Stelle es abbricht. Und zwar dann, wenn die while-Schleife (unten) zum letzten Mal durch läuft.
while( stck_pop(a, &scheibe1) == 0 ) stck_push(b, scheibe1);
-
Hallo!
Dankeschön für die beeindruckend schnelle Hilfe! Ich werde deinen Hinweis gleich austesten ..