Was ist das Problem? (Listen in C)
-
Hallo, ich habe ein Problem beim Ausführen von meine Code:
/* * Funktion: Beispiel einer einfach verketteten Liste (mit einfügen hinten) */ #include <stdio.h> #include <conio.h> #include <stdlib.h> typedef struct ELEMENT { struct ELEMENT *n; // Zeiger auf das nächste Listenelement int inhalt; } Element; /*typedef struct LISTENKOPF { struct LISTENKOPF *erstes; //Zeiger auf das 1. Listenelement int anzahl; } Listenkopf;*/ void ListeAufbauen(Element *kopf, Element *ende, Element *p, int i); void ElementLoeschen(Element *p, Element *kopf, Element *loesch, int gone, int i); void ElementEinfuegenDazwischen(Element *p, Element *kopf); void ListeAusgeben(Element *p, Element *kopf); void main() { Element *p, *ende, *loesch, *kopf; int i, auswahl, gone; i = auswahl = gone = 0; //Schleifenzähler mit 0 initialisieren kopf = ende = loesch = p = NULL; //Alle nötigen Zeiger zeigen nun auf NULL ListeAufbauen(kopf, ende, p, i); ElementLoeschen(p, kopf, loesch, gone, i); ElementEinfuegenDazwischen(p, kopf); ListeAusgeben(p, kopf); } void ListeAufbauen(Element *kopf, Element *ende, Element *p, int i) { int zahl; printf("%d.Listenelement: " ,++i); scanf("%d", &zahl); while(zahl != 0) { p = (Element*)malloc(sizeof(Element)); if (p != NULL) //Wenn die Speicherallokierung erfolgreich war { p->inhalt=zahl; if(kopf==NULL) //Wenn Liste leer (=wenn noch kein Element eingelesen wurde) { kopf=p; ende=p; p->n=NULL; } else //Wenn Liste nicht leer (normalerweise nach einlesen des 1. Elementes) { ende->n=p; p->n=NULL; ende=ende->n; } printf("%d.Listenelement: " ,++i); scanf("%d", &zahl); } else //Wenn kein Speicherplatz reserviert werden konnte { printf("\nZu wenig Speicherplatz"); break; } } } void ElementLoeschen(Element *p, Element *kopf, Element *loesch, int gone, int i) { int loeschNr; p = kopf; //p auf das 1. Element setzen printf("\nWelches Element soll geloescht werden?"); printf("\nEingabe: "); scanf("%d", &loeschNr); while(loeschNr != p->inhalt) { p = p->n; gone++; //Anzahl der Weiterschaltungen wird mitgezählt } p = kopf; for(i=1; i<=gone-1; i++) { p = p->n; } //p zeigt nun auf das Element vor dem zu löschendem Element if(loeschNr == p->inhalt) //Wenn die zu löschende Zahl das 1. Element ist { loesch = p; p = p->n; } loesch = p->n; p->n = loesch->n; free(loesch); } void ElementEinfuegenDazwischen(Element *p, Element *kopf) { Element *newElement, *vorgaenger, *nachfolger; int vorgaengerNr; vorgaenger = nachfolger = NULL; p = kopf; newElement = (Element*)malloc(sizeof(Element)); printf("\n\nNeues Element: "); scanf("%d", &newElement->inhalt); printf("Nach welchem Element soll das neue Element eingefuegt werden?"); printf("\nVorgaenger: "); scanf("%d", &vorgaengerNr); while(vorgaenger != p->inhalt) { vorgaenger = p->n; } //vorgänger wurde gefunden vorgaenger = p; nachfolger = p->n; vorgaenger->n = newElement; newElement->n = nachfolger; } void ListeAusgeben(Element *p, Element *kopf) { printf("\n\nAusgabe der Liste (eventuell wurden Elemente hinzugefuegt)\n\n"); p = kopf; while(p != NULL) { printf("%d\n" , p->inhalt); p = p->n; } getch(); }
Sobald ich das zu löschende Element eingegeben habe und Enter gedrückt habe, stürzt das Programm ab. (mit irgend so einem typischen Adressenfehler,...)
"This is the next statement to execute when this thread returns from the current function" steht dann in Zeile Nr. 93
Bitte um Hilfe
PS: Hab schon alles versucht, das ganze (wie immer) auf ein Blatt Papier aufgezeichnet, etc...hilft aber alles nix (laut meinen Zeichnungen sollte das Programm an sich funktionieren....wenn da dieser Absturz nicht wäre...
)
-
Nimm den Debugger.
Oder schreib mal
//vorZeile 35: printf("vor ListeAufbauen: kopf: %p, ende: %p, p: %p, i: %d\n", kopf, ende, p, i); ListeAufbauen(kopf, ende, p, i); // Zeile 35 //nach Zeile 35: printf("Nach ListeAufbauen: kopf: %p, ende: %p, p: %p, i: %d\n", kopf, ende, p, i);
Schau mal nach ob das die Werte sind, die du erwartest.
-
Naja der Debugger bringt logischerweise nicht viel, wieso sollte er auch? Habs ja ganze Zeit mit dem Debugger ausgeführt, wie denn sonst?
Ok hab das mit den printf's mal eingefügt...vorher ist alles "0" bzw. "0.0000000"....nachdem die Liste aufgebaut wurde ist auch alles "0", außer in "ende" steht irgendeine große Zahl...
Was kann ich daraus schließen?
Danke
-
kopf zeigt immer noch auf NULL.
Du bekommst den Wert vonkopf
nicht ausListeAufbauen
zurück.Da du in den weitern Funktionen aber
kopf == NULL
nicht abfängst, stürzt dein Programm ab.Wie bekommst du jetzt kopf zurück?
Entweder du machst aus kopf einen Doppelzeiger oder
du gibst kopf als Rückgabewert deiner Funktion an. (Also nicht mehr void)
-
Achsoooo ist ja eigentlich logisch:
Das 1. UP funktioniert ja noch, da ich zuerst kopf mit NULL initialisiere und dann verwende. Aber im 2. UP übergebe ich ja noch immer den kopf, der mit "NULL" initialisiert ist...alles klar ich versuch das mal danke
-
Ok, hab die UP jetzt statt void vom Typ "Element*" gemacht.
Jetzt kann ich wenigstens ohne Absturz das zu löschende Element einlesen. Aber nach dem einlesen geschieht einfach nichts....
was ist da los?
-
Was passiert denn bei
printf("vor ListeAufbauen: kopf: %p, ende: %p, p: %p, i: %d\n", kopf, ende, p, i); ListeAufbauen(kopf, ende, p, i); printf("Nach ListeAufbauen: kopf: %p, ende: %p, p: %p, i: %d\n", kopf, ende, p, i); // ElementLoeschen(p, kopf, loesch, gone, i); // ElementEinfuegenDazwischen(p, kopf); ListeAusgeben(p, kopf);
Also nur aufbauen und ausgeben. Ohne löschen.
-
Dann gibt das Programm nachdem ich 0 eingebe in eine Endlosschleife ganze Zeit irgend eine Speicheradresse aus...
-
Warum steppst Du nicht mit dem Debugger durch und guckst Dir die Werte an?
Dann kannst Du auch nachschauen warum Dein Abbruchkriterium nicht zieht.
-
Hast du auch in
ListeAufbauen
einreturn kopf;
?
Und rufst du es mit
kopf = ListeAufbauen([t]Deine Variablen hier[/t]);
auf?