Lineare Liste
-
Huhu, hab ein Problem mit Linearen Listen.
Also, habe eine Liste erstellt wo jeder Datensatz eine ID bekommt. Nun moechte ich durch diese ID einen Datensatz loeschen.Das loeschen ansich ist ja nicht so das Problem, das funktioniert wunderbar. Nur wird die Liste dann unbrauchbar. Wenn ich den selben Datensatz nochmal loeschen moechte, was ansich ja dumm ist ja ^^, kommt folgender Fehler:
*** glibc detected *** double free or corruption (fasttop): 0x0804a008 ***
Abgebrochengeht halt nicht. Die loesch Funktion sieht so aus:
void loeschen(struct Element *top, struct Element *p, int id) { int counter=0, i=0; p=top; while(p!=NULL) { if(p->id==id) { printf("Datensatz: %i wird geloescht!\nInhalt war: %s.\n", p->id, p->datendinger); free(p); } p=p->next; } }
Ich kenn mich mit Linearen Listen so gut wie garnicht aus und versteh die auch nicht wirklich. Aber ich meine zu wissen das der Fehler der ist, dass das Element vor dem geloescht ja nicht mehr weiss, wo das naechste liegt.
Nu zur Frage
Wie kann ich den next Pointer vom vorherigen Element gezielt auf das Element nach dem geloeschten Setzen?
Hab da ettliche Sachen probiert und dabei die umstaendlichsten Schleifen probiert aber nichts hat so wirklich hingehaun. Von countern die mitzaehlen wieviele Elemente es bis zum geloeschten sind bis hin zu ettlichen if abfragen aber naja. Was sagt mein Pauker so gern? Denke zu kompliziert fuer so ne "leichte" Aufgabe.mfg
-
Wenn du free(p) aufrufst, wird der Speicher des Datensatzes aufgeräumt - leider zerlegst du damit auch den Pointer p->next, mit dem du im nächsten Schritt weiter durch deine Liste rennen willst.
Außerdem solltest du den next-Zeiger von p's Vorgänger auch noch an dem gerade gelöschten Objekt vorbeileiten:while(p->next!=NULL) { if(p->next->id==the_id) { struct Element* t=p->next; p->next=t->next; //Vorgänger umleiten free(t); //Element löschen } p=p->next; //weiter in Liste }
-
p->prev->next = p->next; // sowas??
-
Ich habs nun probiert so wie CStoll vorgeschlagen hat, nur hab ich da ein neues Problem mit.
void loeschen(struct Element *top, struct Element *p, int id) { p=top; while(p!=NULL) { if(p->id==id) { struct Element *t = p->next; p->next=t->next; printf("Datensatz: %i wird geloescht!\nInhalt war: %s.\n", t->id, t->datendinger); free(t); } p=p->next; } }
nun mal abgesehen vom Speicherzugriffsfehler wenn ich id 1 loeschen moechte, loescht er nicht die id die ich ihn angebe.
Also ich fuelle die Liste mit 5 Datensaetzen. Die lass ich mir spasseshalber ausgeben:ID: 5, Notiz: 5
ID: 4, Notiz: 4
ID: 3, Notiz: 3
ID: 2, Notiz: 2
ID: 1, Notiz: 1Ist zwar rueckwaerts, aber glaube nicht, dass das das Problem daran ist?
Nun komm ich zum loeschen und sage ihn ID 3 soll geloescht werden, nur leider sieht die Liste dann so aus:ID: 5, Notiz: 5
ID: 4, Notiz: 4
ID: 3, Notiz: 3
ID: 1, Notiz: 1hat also ID 2 geloescht. Will ich ID 5 loeschen, killt er ID 4.
Da dacht ich mir aender ich halt die if:if(p->id==id+1)
Nun ja... nun loescht er zuverlaessig id 2-4. 5 willer nicht.
Was auch noch ein Propblem ist: Wenn ich zweimal die gleiche ID angebe also sag er soll 3 loeschen und dann im anschluss nochmal 3. Loescht er 4...steig da nimmer durch
mfg
-
du musst die ID des folgenden elements pruefen, nicht die des aktuellen elements!
-
ich bin so dumm ^^
wer lesen kann, ist klar im vorteil
hab das next in der if uebersehen.edit:
aber es tut nur, wenn ich den ersten datensatz bzw die erste id zuerst loesche, auf alles andere beendet das prog mit speicherzugriffsfehler..edit:
hab nun herrausgefunden wie ich in der liste "fast" alle Datensaetze loeschen kann.while(p!=NULL) { if(p->next==NULL) //dem if sei Dank :) break; else if(p->next->id==id) { struct Element *t = p->next; p->next=t->next; printf("Datensatz: %i wird geloescht!\nInhalt war: %s.\n", t->id, t->datendinger); free(t); } p=p->next; } }
Nun hab ich nurnoch das Problem, dass er den letzten Datensatz einfach nicht loeschen will.
Was ich auch versuch will er nicht. Ueber Vorschlaege wuerd ich mich sehr freuen, denn ich selber bin mit meinem C-Kenntnissen am ende, wenn ich nicht durch zufall auf die Loesung stosse ^^