Letztes Element einer LinkedList



  • struct LinkedListElement
    {
    	int value;
    	struct LinkedListElement *next;
    };
    
    struct LinkedListElement *Head = NULL;
    
    struct LinkedListElement *getLastElement(void)
    {
    	struct LinkedListElement *tmp = Head;
    
    	if(tmp==NULL)
    		return NULL;
    
    	while(tmp->next != NULL)
    	{
    
    		 tmp = tmp->next;
    	}
    
    	return tmp;
    }
    

    Die Funktion getlastElement() soll das letzte Element in der LinkedList "Head" ausfindig machen - funktioiert leider nicht - wo liegt mein Denkfehler?

    (mir ist klar, dass ich struct LinkedList auch mit einem typdef abkürzen könnte, aber das ist mir jetzt mal egal - außerdem wäre es sicher sinnvoller Die LinkedList als Pramater an die Funktion zu übergeben und nicht einfach Seiteneffekte auszunützen - jedoch gehts mir erst mal nur ums prinzip wie ich das letzte element der LL finde)



  • In der Funktion kann ich keinen Fehler finden. Der muss wo anders sein.



  • Dann poste ich mal den ganzen Code:

    /*
    	Code nach C99 (ISO/IEC 9899:1999)
    */
    
    #include <stdio.h>
    
    struct LinkedListElement
    {
    	int value;
    	struct LinkedListElement *next;
    };
    
    struct LinkedListElement *Head = NULL;
    
    // Fuegt ein Element in die LinkedList ein
    void Insert(int value)
    {
    	struct LinkedListElement *tmp = Head;
    
    	Head = malloc(sizeof(struct LinkedListElement));
    	Head->value = value;
    	Head->next = tmp;
    }
    
    // Zeigt die Liste an
    void Show(void)
    {
    	struct LinkedListElement *tmp = Head;
    	while(tmp != NULL)
    	{
    		printf("%d\n", tmp->value);
    		tmp = tmp->next;	
    	}
    }
    
    // Loescht die LinkedList
    struct LinkedListElement *getLastElement(void)
    {
    	struct LinkedListElement *tmp = Head;
    
    	if(tmp==NULL)
    		return NULL;
    
    	while(tmp->next != NULL)
    	{
    		if(tmp->next==NULL)
    			printf("fehler");
    
    		 tmp = tmp->next;
    	}
    
    	return tmp;
    }
    
    void Delete(void)
    {
    	struct LinkedListElement *tmp = getLastElement();
    
    	while(tmp != NULL)
    	{
    		free(tmp);
    		tmp = getLastElement();
    	}
    }
    
    int main(void)
    {
    	Insert(2);
    	Insert(3);
    	Insert(4);
    	Show();
    	Delete();
    }
    


  • void Delete(void)
    {
    	struct LinkedListElement *tmp = getLastElement();
    
    	while(tmp != NULL)
    	{
    		free(tmp);
    		tmp = getLastElement();
    	}
    }
    

    Das sieht ziemlich verdächtig aus. Du schneidest ja das Ende der Liste einfach ab, und anstatt den next-Zeiger des vorletzten Knotens auf 0 zu setzen zeigt er dann ins Leere. Du machst es im Allgemeinen zu kompliziert, warum denn überhaupt rückwärts löschen?

    void Delete(void) 
    {
      struct LinkedListElement *tmp;
      while (Head != NULL)
      {
        tmp = Head->next;
        free(Head);
        Head = tmp;
      }
    }
    


  • oh da habe ich etwas umständlich gedacht 😞

    wollte meinen Code gerade verbessern und schon steh ich vor dem nächsten Problem:

    /*
    	Code nach C99 (ISO/IEC 9899:1999)
    */
    
    #include <stdio.h>
    
    struct LinkedListElement
    {
    	int value;
    	struct LinkedListElement *next;
    };
    
    typedef struct LinkedListElement *LinkedList;
    
    // Fuegt ein Element in die LinkedList ein
    void Insert(int value, LinkedList LinkedList)
    {
    	struct LinkedListElement *tmp = LinkedList;
    
    	LinkedList = malloc(sizeof(struct LinkedListElement));
    	LinkedList->value = value;
    	LinkedList->next = tmp;
    }
    
    // Zeigt die Liste an
    void Show(LinkedList LinkedList)
    {
    	struct LinkedListElement *tmp = LinkedList;
    	while(tmp != NULL)
    	{
    		printf("%d\n", tmp->value);
    		tmp = tmp->next;	
    	}
    }
    
    // Loescht die LinkedList
    void Delete(LinkedList LinkedList) 
    { 
    	struct LinkedListElement *tmp; 
    	while (LinkedList != NULL) 
    	{ 
    		LinkedList = LinkedList->next; 
    		free(LinkedList); 
    		LinkedList = tmp; 
    	} 
    } 
    
    // Erzeugt eine LinkedList
    void Create(LinkedList LinkedList)
    {
    	LinkedList = NULL;
    }
    
    int main(void)
    {
    	LinkedList Liste;
             Create(Liste);
    
    	Insert(5, Liste);
    	Insert(10, Liste);
    	Insert(12, Liste);
    
    	Show(Liste);
    
    	Delete(Liste);
    }
    

    Show(Liste) zeigt mir nicht an... mmmh?



  • DAS Compiliert?

    void Create(LinkedList LinkedList)
    {
        LinkedList = NULL;
    }
    


  • nö - aber das akzeptiert mein Compiler:

    #include <stdio.h> 
    
    struct LinkedListElement 
    { 
        int value; 
        struct LinkedListElement *next; 
    }; 
    
    typedef struct LinkedListElement *LinkedList; 
    
    // Fuegt ein Element in die LinkedList ein 
    void Insert(int value, LinkedList LinkedList) 
    { 
        struct LinkedListElement *tmp = LinkedList; 
    
        LinkedList = malloc(sizeof(struct LinkedListElement)); 
        LinkedList->value = value; 
        LinkedList->next = tmp; 
    } 
    
    // Zeigt die Liste an 
    void Show(LinkedList LinkedList) 
    { 
        struct LinkedListElement *tmp = LinkedList; 
        while(tmp != NULL) 
        { 
            printf("%d\n", tmp->value); 
            tmp = tmp->next;    
        } 
    } 
    
    // Loescht die LinkedList 
    void Delete(LinkedList LinkedList) 
    { 
        struct LinkedListElement *tmp; 
        while (LinkedList != NULL) 
        { 
            LinkedList = LinkedList->next; 
            free(LinkedList); 
            LinkedList = tmp; 
        } 
    } 
    
    int main(void) 
    { 
        LinkedList Liste=NULL; 
    
        Insert(5, Liste); 
        Insert(10, Liste); 
        Insert(12, Liste); 
    
        Show(Liste); 
    
        Delete(Liste); 
    }
    

    was mach ich da falsch



  • Versuch mal das hier.

    /* 
        Code nach C99 (ISO/IEC 9899:1999) 
    */ 
    
    #include <stdio.h>
    #include <malloc.h>
    #include <stdio.h> 
    
    struct LinkedListElement 
    { 
        int value; 
        struct LinkedListElement *next; 
    }; 
    
    typedef struct LinkedListElement *LinkedList; 
    
    // Fuegt ein Element in die LinkedList ein 
    void Insert(int value, LinkedList *LinkedList) 
    { 
        struct LinkedListElement *tmp = (*LinkedList); 
    
        (*LinkedList) = (LinkedListElement*)malloc(sizeof(struct LinkedListElement)); 
        (*LinkedList)->value = value; 
        (*LinkedList)->next = tmp; 
    } 
    
    // Zeigt die Liste an 
    void Show(LinkedList LinkedList) 
    { 
        struct LinkedListElement *tmp = LinkedList; 
        while(tmp != NULL) 
        { 
            printf("%d\n", tmp->value); 
            tmp = tmp->next;     
        } 
    } 
    
    // Loescht die LinkedList 
    void Delete(LinkedList LinkedList) 
    { 
        struct LinkedListElement *tmp=NULL; 
        while (LinkedList != NULL) 
        { 
            LinkedList = LinkedList->next; 
            free(LinkedList); 
            LinkedList = tmp; 
        } 
    } 
    
    int main(void) 
    { 
        LinkedList Liste=NULL; 
    
        Insert(5, &Liste); 
        Insert(10, &Liste); 
        Insert(12, &Liste); 
    
        Show(Liste); 
    
        Delete(Liste); 
    
    	return 0;
    }
    

    *EDIT* Ein Include zuviel 🙄



  • ups... Zeiger auf Zeiger - da fällt mir jetzt wieder was ein



  • Netzwerk-Latenz schrieb:

    // Loescht die LinkedList 
    1: void Delete(LinkedList LinkedList) 
    2: { 
    3:    struct LinkedListElement *tmp=NULL; 
    4:    while (LinkedList != NULL) 
    5:    { 
    6:        LinkedList = LinkedList->next; 
    7:        free(LinkedList); 
    8:        LinkedList = tmp; 
    9:    } 
    10:}
    

    ist das nicht ein Memory Leak?

    in Zeile 8 setzt du LinkedList auf den Wert NULL - damit ist die Schleife beendet - es wird maximal einmal free aufgerufen



  • // Loescht die LinkedList 
    void Delete(LinkedList *LinkedList) 
    { 
    	struct LinkedListElement *tmp  = NULL;
    	while(*LinkedList != NULL)
    	{
    		tmp = (*LinkedList)->next;
    		free(*LinkedList);
    		*LinkedList = tmp;
    	}
    }
    

    irgendwie funzt das auch wieder nicht - kann aber keinen fehler erkennen...



  • // Loescht die LinkedList 
    void Delete(LinkedList LinkedList) 
    { 
        struct LinkedListElement *tmp=NULL;
    
        while (LinkedList != NULL) 
        { 
    		tmp = LinkedList->next;
            free(LinkedList); 
            LinkedList = tmp; 
        } 
    }
    

    Und so.



  • Die Funktion Delete bekommt ja bei deiner Version nur eine Kopie der Adresse geliefert, wobei bei meiner Version call by reference stattfindet - ich will die übergebene liste nachdem ich sie "deletet" habe auf NULL setzten - das geht halt nur wenn ich call by reference mach



  • kann mir jemand meinen Fehler bei Folgender Funktion sagen (der Funktionskopf soll nicht verändert werden):

    // Loescht die LinkedList 
    void Delete(LinkedList *LinkedList) 
    { 
        struct LinkedListElement *tmp  = NULL; 
        while(*LinkedList != NULL) 
        { 
            tmp = (*LinkedList)->next; 
            free(*LinkedList); 
            *LinkedList = tmp; 
        } 
    }
    


  • Ich finde, du solltest erstmal ausschlafen, oder alternativ das Kapitel Zeiger (inkl. * und -> Operatoren) nochmal überfliegen. Das kann eigentlich nicht sein, dass man solche Fehler nicht selber findet.


Anmelden zum Antworten