K2DaC Geschrieben 23. Mai 2009 Geschrieben 23. Mai 2009 Hi ! Bin neu hier und hab auch gleich mal ne frage ! Hab ein Problem bei einem Projekt wo wir eine Verkettete Liste erstellen sollen Die Liste ansich ist nicht wirklich mein Problem. Eher das die Liste "allgemein" sein soll. Also vom "inhalts"-Typen unabhängig. Die liste kann also int, strings als auch structs "verarbeiten", bzw mit den gleichen funktionen hinzufügen usw. Hier mal kurz die liste typedef struct Knoten { struct Knoten* next ; void* content ; } Knoten ; typedef struct Liste { Knoten* first ; Knoten* last ; int size ; } Liste ; void printList(Liste* l, void (*printContent) (void*)) ; void appand(Liste* l, void* value) ; und hier die Funktionen der liste #include <stdio.h> #include <stdlib.h> #include "Listen.h" void printList(Liste* l, void (*printContent) (void*)) { Knoten* k = l->first ; while (k!=NULL) { printContent(k->content) ; k = k->next ; } } void appand(Liste* l, void* value) { Knoten* neu = (Knoten*) malloc(sizeof(Knoten)) ; if (neu == NULL) { printf("Kein Arbeitsspeicher mehr vorhanden!\n") ; exit(EXIT_FAILURE) ; } ; (*neu).next = NULL ; neu->content = value ; if (l->size == 0) { l->first = neu ; } else { Knoten* letzterKnoten = l->last ; letzterKnoten->next = neu ; } ; l->last = neu ; l->size++ ; // Anzahl der Knoten in der Liste um 1 erhöhen. } Das ganze funktioert auch ! Nun sollen Daten aus einer Textdatei eingelesen werden, und in die liste hinzugefügt werden. Das ganze klappt bei mir nur, wenn meine Textdatei genau eine Zeile hat. Bei zwei zeilen wird die erste überschrieben, und recht abgehackt ausgegeben! Grund, meine "eingelesenen" wörter (mit fgets aus der txt datei eingelesen & mit strtok in einzelne wörter zerteilt) gammeln irgendwo im speicher ohne das speicher reserviert wurde. Soweit sogut. Aber WO soll ich denn speicher reservieren, wenn die liste für den speicher selbst verantwortlich sein soll ? Sobald ich bei appand anfange speicher für "strings" zu reservieren (mal abgesehen davon, dass ich das nichtmal hinbekommen habe bisher), wird das ganze doch wieder auf strings "begrenzt". gibt es eine möglichkeit heraus zu bekommen, welcher typ an "appand" übergeben wurde und dann mit ner if anweisung für den entsprechenden typ speicher zu reservieren ? Hoffe ich habe mein Problem halbwegs verständlich rübergebracht. Ist für die Uni, und ich hab mal wieder viel zu spät angefangen mich damit zu beschäftigen ... Und damit der lerneffekt erhalten bleibt, bin ich über tips / hinweise dankbarer als über vorgefertigte lösungen (halb gelogen aber egal ;P ) Zitieren
Klotzkopp Geschrieben 23. Mai 2009 Geschrieben 23. Mai 2009 Aber WO soll ich denn speicher reservieren, wenn die liste für den speicher selbst verantwortlich sein soll ?Wer sagt denn, dass sie das soll? gibt es eine möglichkeit heraus zu bekommen, welcher typ an "appand" übergeben wurde und dann mit ner if anweisung für den entsprechenden typ speicher zu reservieren ?Selbst wenn das möglich wäre: Dadurch, dass man durch Structs beliebig neue Typen definieren kann, müsstest du eine unendlich große If-Kaskade bauen. Du könntest zusätzlich die Größe des Wertes übergeben, ein entsprechend großes char-Array bereitstellen und umkopieren. Dann müsste der Benutzer der Liste aber beim Zugriff auf die gespeicherten Elemente wieder in ein Objekt des passenden Typs umkopieren, weil nicht garantiert ist, dass ein char-Array für einen beliebigen anderen Typ passend ausgerichtet ist - Stichwort Alignment. Und selbst das klappt nicht, wenn die Elemente selbst Strukturen sind, die wiederum Zeiger auf Speicher enthalten, der wer weiß wo verwaltet wird. Was machst du denn, wenn bei der Typanalyse rauskommt, dass value ein Zeiger auf struct xyz { unsigned long* data_array; unsigned char* not_zero_terminated; struct xyz* next; };[/CODE] ist? In C kann eine generische Liste nicht den Speicher ihrer Elemente verwalten. Das bleibt Aufgabe des Benutzers. Zitieren
flashpixx Geschrieben 23. Mai 2009 Geschrieben 23. Mai 2009 In C kann eine generische Liste nicht den Speicher ihrer Elemente verwalten. Das bleibt Aufgabe des Benutzers. Vielleicht etwas praktischer formuliert: Die Liste ist ein Konstruktur aus einem Zeiger, der auf das aktuelle Element zeigt und ein solches Element besteht aus einem Zeiger auf die Daten und einem Zeiger auf das nächste Element. Z.B. kann der Benutzer dann ints, chars oder beliebige andere Strukturen erzeugen und übergibt der Liste beim hinzufügen eines Elementes nur den Zeiger auf dieses Element. Das Abfragen eines Elementes, liefert dann nicht das Element, sondern nur den Zeiger darauf Phil Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.