Listen und ihre Tücken
-
Hey, ich bin neu im Forum, also erstmal hallo an alle
Ich habe wie der Titel evtl. schon vermuten lässt ein kleines Problem mit dem erstellen eine Liste, besser gesagt einer sortierten Liste m.H. eines Anfangs und Ende Pointers.
erstmal der Code
void anhaengen_anfang_ende_sort (int inha, struct Liste1 **p_pointer_anfang,struct Liste1 **p_pointer_ende) { struct Liste1 *zeiger, *zeiger_neu, *zeiger_anfang; printf("\n\nInhalt: %d\n",inha); if(*p_pointer_anfang==NULL) // erstes Elemenet einfügen { zeiger=malloc(sizeof(struct Liste1)); zeiger->inhalt = inha; zeiger->next=NULL; zeiger->prev=NULL; *p_pointer_anfang=zeiger; *p_pointer_ende=zeiger; printf("1. Element erzeugt\n"); } else { zeiger_anfang=*p_pointer_anfang; zeiger=*p_pointer_anfang; printf("ich allokiere speicher\n"); zeiger_neu=malloc(sizeof(struct Liste1)); zeiger_neu->inhalt=inha; printf("ich allokiere speicher\n"); if(zeiger_neu->inhalt < zeiger_anfang->inhalt) { zeiger_anfang->prev=zeiger_neu; zeiger_neu->next=zeiger_anfang; zeiger_neu->prev=NULL; zeiger_anfang=zeiger_neu; *p_pointer_anfang=zeiger_neu; printf("2. Element erzeugt\n"); } else { printf("Hallo Test\n"); while (zeiger->next !=NULL )//&& zeiger->next->inhalt < inha) { printf("!!!Hallo Test\n"); zeiger=zeiger->next; } zeiger_neu=malloc(sizeof(struct Liste1)); zeiger_neu->inhalt=inha; zeiger_neu->next=zeiger->next; zeiger->next=zeiger_neu; printf("3. Element erzeugt\n"); } } printf("anfang_ende_sort - Element erzeugt\n"); }
Ich gebe inhalt, mit rand () gefüllt, mit und die pointer sind jeweils nil;
die structur sieht so aus.struct Liste1 { int inhalt; struct Liste1 *next; struct Liste1 *prev; };
So folgendes Problem, die ersten beiden elemente zu erzeugen und mit einandere zu verketten läuft ohne Probleme, wenn das 3. Element so groß ist das es zwischen den beiden Elementen eingefügt werden muss tritt ein Fehler beim allokieren des Speichers an folgender Stelle auf.
printf("ich allokiere speicher\n"); zeiger_neu=malloc(sizeof(struct Liste1)); zeiger_neu->inhalt=inha; printf("ich allokiere speicher\n");
mit gdb komm ich nicht weiter, weil er ebend auf malloc verweist und nach nun fast 3 Stunden des probierens und nachdenkens bin ich leicht verzweifelt. Ich hoffe Ihr könnt mein Hirn in die richtige Richtung lenken
mfg
-
Wo tritt der Fehler (Zeile) auf und wie lautet er genau?
Was soll die Zeile 49. Den Speicher hast du schon in Zeile 25 besorgt.Hast du beim Compiler alle Warnungen angeschaltet
-
Ich hab den Fehler versucht mit print Befehlen zu lokalisieren und demnach tritt er in Zeile 25 auf, Die Zeilen ab 49 hab ich gelöscht, war wirklich unnötig...
beim compilieren treten keine fehler auf, erst beim ausführen, falls du das meinst.
-
Zeile 25 (was seltsam wäre) oder Zeile 26?
Schon mal direkt nach dem malloc:
printf("malloc liefert: %p\n", zeiger_neu);
gemacht und auf den Wert geachtet?
Und es tritt beim 3. Element auf?
Mit welchen werten versuchst du das denn (Reihenfolge ist auch wichtig)Ich vermisse das Umbiegen von
p_pointer_ende
beim 2. (letzten) ElementWie rufst du die Funktion denn auf?
-
Doch ist Zeile 25, nehme ich zumindest an, weil...
1. er gibt das erste "ich allokiere speicher" aus, danach kommt Seg. fault
2. via backtrace kommt diese Fehlermeldung vom Debugger(gdb) backtrace
#0 _int_malloc (av=0x7ffff7dd3720, bytes=24) at malloc.c:3463
#1 0x00007ffff7a9dfb5 in __GI___libc_malloc (bytes=24) at malloc.c:2924
#2 0x0000000000400bca in anhaengen_anfang_ende_sort ()
#3 0x00000000004018db in main ()Die Werte die malloc liefert sind veränderlich, so wie es sein sollte, denke ich.
Was meinst du ob es beim 3. Element auftritt?
Aufrufen wird die Funktion so:
for(x=0; x<laenge; x++) { inha=rand () % 100; anhaengen_anfang_ende_sort(inha, &p_anfang, &p_ende); }
-
Bei mir funktioniert es soweit.
Visual Studio 2008 Express unter XP:int main(int argc, char* argv[]) { int x, inha, laenge = 10; struct Liste1 *p_ende=NULL, *p_anfang=NULL; for(x=0; x<laenge; x++) { inha=rand () % 100; anhaengen_anfang_ende_sort(inha, &p_anfang, &p_ende); } return 0; }
-
Ich glaube es liegt vielmehr an meiner methode zum löschen der Listen, das dort iwelche Adressen nicht wieder richtig frei gegeben werden.
Hab da grad nen bisschen drin rumgeschrieben und den Fehler noch etwas ausgebaut
void loeschen_alles(struct Liste1** p_pointer_anfang, struct Liste1** p_pointer_ende) { struct Liste1 *zeiger, *zeiger1, *zeiger2; struct Liste1 *zeiger_anfang=*p_pointer_anfang; struct Liste1 *zeiger_ende=*p_pointer_ende; // Liste vorhanden? if(zeiger_anfang != NULL) { zeiger=zeiger_anfang->next; //zeiger zeigt auf das 2. Element while(zeiger->next->next != NULL) { zeiger1=zeiger_anfang->next->next; // zeiger1 zeigt auf das 3. Element zeiger_anfang->next=zeiger1; // zeiger_anfang->next zeigt auf zeiger1 free(zeiger); //das 2. Element wird gelöscht zeiger=zeiger1; //zeiger zeigt nun auf das 3. Element } free (*p_pointer_anfang); free (*p_pointer_ende); zeiger_anfang = NULL; zeiger_ende = NULL; printf("Liste erfolgreich gelöscht!\n"); } else { printf("Keine Liste zum löschen vorhanden!\n"); } }
hab ich dort iwie nen Denkfehler drin, ich find eig das sieht ganz gut aus...
-
Was ist, wenn deine Liste nur ein Element hat (und das hat sie irgendwann)?
Dann crasht das ->next->next;
Warum free (*p_pointer_anfang) und free (*p_pointer_ende) ?
Die Knoten hast du doch schon in der Schleife freigegeben.Ungetestet:
void loeschen_alles(struct Liste1** p_pointer_anfang, struct Liste1** p_pointer_ende) { struct Liste1 *zeiger; struct Liste1 *zeiger_anfang=*p_pointer_anfang; while(zeiger_anfang != NULL) // solange ein Element in der Liste ist { zeiger=zeiger_anfang->next; // nächstes Element merken free(zeiger_anfang); zeiger_anfang=zeiger; } *p_pointer_anfang = NULL; *p_pointer_ende = NULL; }
-
stark
hast mir sehr geholfen, danke, läuft jetzt fast alles!