ungeordnete Liste
-
Hallo,
ich habe versuche gerade meine erste Liste hinzukriegen, aber leider ist dort
irgendwo eine Katze im Sack! Ich habe mich nur auf die Theorie der Wiki bezogen,
also keine Quellen zur Hand, falls ihr fragt.Hier mal mein Code (Ansi C):
#include <stdio.h> #include <stdlib.h> typedef struct listdef { int Key; struct NewList *Next; }NewList; void *l_init(NewList *l); void *l_insert(NewList *l, int value); int main(int argc, char *argv[]) { NewList *liste; l_init(liste); int myarray[2], i; printf("Gebe drei Zahlen nacheinander ein!\n\n"); for(i=0; i<3; i++) { scanf("%d", &myarray[i]); l_insert(liste, myarray[i]); } while (liste->Next != NULL) { printf("%d\n\n", liste->Key); } while (liste != NULL){ free(liste); } system("PAUSE"); return 0; } void *l_init(NewList *l) { l = malloc(sizeof(NewList)); l = NULL; }; void *l_insert(NewList *l, int value) { NewList *Dummy; if (l!=NULL) { l_insert(l->Next, value); } else { Dummy = malloc(sizeof(NewList)); Dummy->Key = value; Dummy->Next = l; l = Dummy; } };
-
Mit welchem Buch lernst du?
3dprogger schrieb:
void *l_init(NewList *l) { l = malloc(sizeof(NewList)); l = NULL; }; void *l_insert(NewList *l, int value) { NewList *Dummy; if (l!=NULL) { l_insert(l->Next, value); } else { Dummy = malloc(sizeof(NewList)); Dummy->Key = value; Dummy->Next = l; l = Dummy; } };
Beide Funktionen machen nichts außer Speicherlecks zu verursachen. C kennt keine Referenzen, alle Parameter sind Kopien. Du übergibst also eine Kopie eines Zeigers auf ein NewList. Diese Kopier veränderst du in der Funktion, nicht jedoch die ursprüngliche Variable.
Lösung 1: Doppelzeiger
void init(NewList **l) { assert(l != NULL); // Sicher stellen, dass es l gibt *l = malloc(sizeof(NewList)); // l zuerst dereferenzieren, damit du auf die Zeigervariable schreibst. } ... NewList *myList; init(&myList); // Addresse der Variable übergeben
Lösung 2: Rückgabewerte nutzen
NewList* init(void) { NewList *n = malloc(sizeof(NewList)); return n; } ... NewList *myList = init();
-
Mit welchem Buch lernst du?
C von A bis Z
Allerdings habe ich die Thematik noch nicht durchgenommen. Es ist aus einem Pascal Dialekt umgeschrieben.Beide Funktionen machen nichts außer Speicherlecks zu verursachen.
Ist möglich. Da weiß ich nichts von. Aber deinen Rat werde ich nicht vernachlässigen.
C kennt keine Referenzen, alle Parameter sind Kopien.
Das würde ich für ein Gerücht halten, da es doch nicht umsonst CBV und CBR gibt?!
Dann noch sind das im eigentlichen Sinne Prozeduren, was auch das void ausdrücken soll. Deshalb verstehe ich nicht die Idee ein return zu verwendenIch werde es mal ausprobieren!
Danke
Edit: Ich hatte vergessen zu erwähnen, dass das Programm beim rekursiven Aufruf scheitert, d.h. das Problem besteht noch.
-
3dprogger schrieb:
C kennt keine Referenzen, alle Parameter sind Kopien.
Das würde ich für ein Gerücht halten, da es doch nicht umsonst CBV und CBR gibt?!
Dann noch sind das im eigentlichen Sinne Prozeduren, was auch das void ausdrücken soll. Deshalb verstehe ich nicht die Idee ein return zu verwendenAlle Parameter in C sind Kopien. Sowas wie "var Parameter:Typ" wie in Pascal gibt es in C nicht. Daher musst du mit Zeigern auf Variablen eben trickens. Wenn die Variable einen Zeiger speichern soll, dann brauchst du eben Zeiger auf Zeiger.
Und die Return-Methode soll im Prinzip eine Funktion sein, die den neuen ersten Listenknoten zurückgibt. Eben zur Alternative zur Prozedur.
3dprogger schrieb:
Edit: Ich hatte vergessen zu erwähnen, dass das Programm beim rekursiven Aufruf scheitert, d.h. das Problem besteht noch.
Natürlich scheitert es da, weil die Funktion nichts macht, außer Speicherlecks zu produzieren. Aus genau dem Grund, den ich im ersten Beitrag erwähnt habe.
-
Das mit den Kopien ist echt doof. Das wurde im Buch nicht erwähnt oder ich habe es übersehen.
Ich werde einfach mal im Buch das Kapitel durchgehen. Ich dachte es ist ähnlich wie in Pascal
Danke für deine Hinweise, sonst hätte ich Stunden gesessen
-
Es ist wie in Pascal, nur dass es eben das "var" Keyword nicht gibt.
In Pascal kannst du auch Kopien von Zeigern übergeben.
-
3dprogger schrieb:
Dann noch sind das im eigentlichen Sinne Prozeduren, was auch das void ausdrücken soll. Deshalb verstehe ich nicht die Idee ein return zu verwenden
Da das nicht kommentiert wurde: Deine Funktionen sind in der Tat echte Funktionen, da sie nicht den Rückgabetyp
void
(was man mit Pascals Prozeduren vergleichen könnte) sondernvoid*
, also Zeiger aufvoid
, haben.Normalerweise sollte ein Compiler auch meckern, wenn man in so einer Funktion kein
return
hat. Schau mal, ob du nicht irgendwie erreichen kannst, dass mehr Warnungen ausgegeben werden.