Problem mit einfach-verketteter Liste



  • Hallo,

    hier ohne umschweife mein code:

    // abc.h
    typedef struct {
    	struct abc *next;
    	int randomNumber;
    } abc;
    
    abc *new_abc(abc *next);
    void add_abc(abc *main, abc *node);
    
    // abc.c
    #include "abc.h"
    
    #include <stdlib.h>
    
    abc *new_abc(abc *next)
    {
    	abc *node=malloc(sizeof(abc));
    	node->next=(abc *)next;
    
    	return node;
    }
    
    void add_abc(abc *main, abc *node)
    {
    	abc *trash=main;
    
    	while( trash != NULL) {
    		trash=trash->next;
    	}
    
    	trash=node;
    }
    
    // test.c
    #include "abc.h"
    #include <stdio.h>
    
    int main()
    {
    	abc *main=new_abc(NULL);
    	main->randomNumber=0;
    
    	abc *node=new_abc(NULL);
    	node->randomNumber=1;
    
    	add_abc(main,node);
    
    	// alles ausgeben
    	abc *trash=main;
    
    	while( trash != NULL) {
    		printf("Pointer: 0x%p\n",trash);
    		printf("Next-Pointer: 0x%p\n",trash->next);
    		printf("randomNumber: %d\n",trash->randomNumber);
    		printf("***********************************\n");
    		trash=trash->next;
    	}
    	return 0;
    }
    

    Compiliert mit:
    gcc test.c abc.c -o test.exe

    Problem 1: Seltsame und mir unerklärliche Compilermeldungen:

    test.c: In function 'main':
    test.c:22:8: warning: assignment from incompatible pointer type [enabled by defa
    ult]
    abc.c: In function 'new_abc':
    abc.c:8:12: warning: assignment from incompatible pointer type [enabled by defau
    lt]
    abc.c: In function 'add_abc':
    abc.c:18:8: warning: assignment from incompatible pointer type [enabled by defau
    lt]

    Ich habe das umgecastet, und trotzdem werden diese Warnungen ausgegeben?!?

    Problem 2: Das Programm macht nicht das, was es soll.
    Die Ausgabe lautet:

    Pointer: 0x00A80EB0
    Next-Pointer: 0x00000000
    randomNumber: 0
    ***********************************

    Das ist nur ein Teil, denn eigentlich hatte die Liste zwei Einträge, der zweite wird aber irgendwie nicht angehängt. Was ist da falsch?

    Lg und vielen dank im voraus für antworten.



  • Kannste das bitte in eine einzige Datei machen, damit der Helfer es nur per Copy&Paste sich reinkopieren muss um zu testen?



  • typedef struct {
    	struct abc *next;
    	int randomNumber;
    } abc;
    
    abc *new_abc(abc *next);
    void add_abc(abc *main, abc *node);
    
    #include <stdlib.h>
    
    abc *new_abc(abc *next)
    {
    	abc *node=malloc(sizeof(abc));
    	node->next=(abc *)next;
    
    	return node;
    }
    
    void add_abc(abc *main, abc *node)
    {
    	abc *trash=main;
    
    	while( trash != NULL) {
    		trash=trash->next;
    	}
    
    	trash=node;
    }	
    
    #include <stdio.h>
    
    int main()
    {
    	abc *main=new_abc(NULL);
    	main->randomNumber=0;
    
    	abc *node=new_abc(NULL);
    	node->randomNumber=1;
    
    	add_abc(main,node);
    
    	// alles ausgeben
    	abc *trash=main;
    
    	while( trash != NULL) {
    		printf("Pointer: 0x%p\n",trash);
    		printf("Next-Pointer: 0x%p\n",trash->next);
    		printf("randomNumber: %d\n",trash->randomNumber);
    		printf("***********************************\n");
    		trash=trash->next;
    	}
    	return 0;
    }
    

  • Mod

    typedef struct {
        struct abc *next;
        int randomNumber;
    } abc;
    

    Definiert eine unbenannte (d.h. ohne Tagname) Struktur, und gibt ihr den typedef-Namen abc.

    struct abc *next;
    

    in der Strukturdefinition definiert einen Zeiger auf eine Struktur mit dem Tagnamen abc. Die hat nichts mit der von dir definierten Struktur zu tun.

    typedef struct abc {
        struct abc *next;
        int randomNumber;
    } abc;
    

    sollte die (berechtigten) Warnungen eliminieren.



  • ja, die warnungen sind jetzt weg. danke.

    aber das programm funktioniert immernoch nicht, wie es soll. der listeneintrag "node" wird nicht an "main" angehängt.



  • Du solltest auch trash->next einen anderen Wert zuweisen.
    Überleg aber mal, welchen Wert trash hat, nachdem die while -Schleife fertig ist.



  • mhh, ich weiß nicht so ganz, worauf du anspielen willst.

    trash hat nach dem ende der while-schleife den wert NULL. dieses NULL wird mit der adresse des nodes überschrieben, das hinzugefügt werden soll.

    oder täusch ich mich da?



  • Ja, daher kannst du da nicht trash->next nehmen.

    Der Pointer trash ist lokal. Der ist kein Bestandteil der Liste.

    Der ist so wie dein Finger, wenn du auf die Knoten zeigst.
    Mal es dir mal auf.



  • DirkB schrieb:

    Ja, daher kannst du da nicht trash->next nehmen.

    Der Pointer trash ist lokal. Der ist kein Bestandteil der Liste.

    Der ist so wie dein Finger, wenn du auf die Knoten zeigst.
    Mal es dir mal auf.

    ok, aber wie soll ich das dann machen?



  • DirkB schrieb:

    Du solltest auch trash->next einen anderen Wert zuweisen.

    Du musst die Schleife beenden, wenn trash->next NULL ist.

    Beachte aber, dass auch trash schon NULL sein kann.



  • also meinst du das jetzt so:

    // ...
    while( trash->next != NULL)
    {
         trash=trash->next;
    }
    trash=node;
    

    sorry, wenn das jetzt nicht stimmt. ich steh grad voll aufm schlauch.



  • Das next soll doch immer auf das nächste Element verweisen.
    Also musst du auch dieses next verändern. Und zwar von dem Vorgänger.

    node->next = trash->next; // damit die Verkettung erhalten bleibt
    trash->next = node; // einbauen
    


  • ok, jetzt funktioniert alles. danke!


Anmelden zum Antworten