Löschen einer verketteten Liste



  • Hallo,

    hab mal wieder ein Speicherleck in meinem Programm gefunden 😉
    Versuche es zu stopfen sind gescheitert...

    Ich erstelle eine verkettete Liste und geb den Pointer aufs 1. Element zurück:

    EINTRAG * zufallsdaten(int iNumber, int * iDatasets)
    

    Diese Liste halte ich mir als satic in dieser Funktion:

    EINTRAG * SortedListContainer(int iGetNewList, int iCriterion, int iAscending) {
    	static EINTRAG * listStart;
    	int iDataSets;
    	if (iGetNewList)
    		{
    		/* Vorhande Liste Löschen */
    		if (datasetCountContainer(-1) > 0) { /* Falls Datensätze vorhanden */
    			int i;
    			for (i = 0; i < datasetCountContainer(-1); i++) 
    				{
    				printf("#%i#",i);
    				if (i > 0)
    				{
    					printf("#%s#","s");
    					free(listStart->prev);
    					printf("#%s#","e");
    				}
    				printf("%c",'\n');
    				listStart = listStart->next;
    			}
    		}	
    		listStart = zufallsdaten(500, &iDataSets); /* Hier hol ich mir die Liste ab */
    		datasetCountContainer(iDataSets); /* Speichert Anzahl der Datensätze */
    		listStart = sort_list(listStart, iCriterion, iAscending); /* Liste wird sortiert */
    	}
    	return (listStart);
    }
    

    Der 1. Aufruf von SortedListContainer läuft glatt. Es gibt auch noch keine Daten deswegen wird die Löschschleife nicht ausgeführt.
    Wenn ich dann aber sortierte stürzt das Programm beim Listen löschen ab

    Folgende Ausgabe bekomme ich noch auf den Bildschrim

    #0#
    #1##s##e#
    #2##s#
    

    Als Fehlermeldung erhalte ich:

    Unhandled exception at 0x00418dd9 in vms.exe: 0xC0000005: Access violation reading location 0xfeeeff62.
    

    Der Absturz erfolgt bei dieser Code Zeile:

    free(listStart->prev);
    

    Wie kann ich also die Liste löschen ohne das mein programm dabei stirbt?



  • Kann es sein das ->prev beim ersten element irgendwohin in die Walachei zeigt.
    Wahrscheinlich must du zum Ende der Liste gehen und dann mit deiner Methode arbeiten.
    Die Arbeit würde ich dann beenden wenn list->prev auf NULL zeigt.
    Wenn du den RootKnoten anlegst würde ich sicherstellen das ->prev mit NULL initialisiert ist.

    free(listStart->prev);



  • Habe keine Ahnung wie deine, scheinbar doppelt verkettete Liste, organisiert ist aber irgendwo ist da der Wurm drin in deiner logik.mit

    free(listStart->prev);
    

    willst du wahr scheinlich das letze element der liste löschen. ( warum nicht ? ). Danach änderst du aber mit

    listStart = listStart->next;
    

    den begin der liste, und setzt bei keinem element die verkettung neu.
    Da Stimmt was nicht.
    Kurt



  • Ich habs jetzt nochmal ohne sort_list getestet.
    Jetzt funktioniert das Löschen der Lite ohne Probleme.
    Da muß ich mir das wohl nochmal anschauen...



  • DFI10X schrieb:

    Ich habs jetzt nochmal ohne sort_list getestet.
    Jetzt funktioniert das Löschen der Lite ohne Probleme.
    Da muß ich mir das wohl nochmal anschauen...

    Dann liegt es wohl nahe, dass du beim Sortieren deine Zeiger falsch setzt; schätzungweise deinen prev zeiger.

    Dein Löschen ist auch noch nicht komplett. Dir bleibt nämlich 1 Datensatz übrig. Bzw. könntest du Probleme bekommen, wenn in listStart->next 0 drin steht und du die Schleife nochmal ausführst! Besser wäre, wenn du deine Löschschleife solange laufen lässt bis in listStart->next 0 steht und du dann listStart auch noch mit free() freigibst ;).

    Deine Funktion datasetCountContainer() liefert bei -1 schätzungsweise die Anzahl der Datensätze zurück und setzt die Anzahl, wenn der Wert positiv bzw. 0 ist, richtig? Die solltest du evtl. auch noch nach deiner Löschschleife aufrufen mit dem Parameter 0.


Anmelden zum Antworten