Funktionsaufruf (Übergabeparameter = Zeiger)
-
Guten Tag,
habe nun vor 2-3 Tagen mit Zeigern begonnen und gleich die dynamische Speicherverwaltung mit eingebunden.
Nur verstehe ich das Prinzip der Zeiger noch nicht wirklich, was man auch anhand dieses Beispiels sehen mag:typedef struct { int tag; int monat; int jahr; }Datum; void eingabe(Datum *dat); void ausgabe(Datum *dat); int main() { Datum dat; eingabe(&dat); ausgabe(&dat); getch(); return 0; } void eingabe(Datum *dat) { dat = (Datum*)malloc(sizeof(Datum)); //ohne diese Zeile würde das Programm funktionieren printf("Tag: "); scanf("%d", &dat->tag); printf("Monat: "); scanf("%d", &dat->monat); printf("Jahr: "); scanf("%d", &dat->jahr); } void ausgabe(Datum *dat) { printf("%d.%d.%d", dat->tag, dat->monat, dat->jahr); }
Aber wieso? Ich blicke einfach nicht durch - hoffe ihr könnt mir helfen.
-
Hmm, mir ist zwar klar, wieso das Programm mit dem malloc nicht funktioniert, aber ich verstehe nicht, wie du überhaupt da drauf kommst, dort ein malloc einzufügen. Daher ist es schwer, dir den Fehler zu erklären :p .
Also was hier passiert: In deiner main lebt ein struct Datum. Das ist ein vollständiges Objekt, mit eigenem Speicherbereich und allem. Du übergibst an deine Eingabe einen Zeiger auf diesen Speicherbereich. Genauer gesagt die Kopie eines Zeigers auf diesen Speicherbereich. Das heißt, deine eingabe-Funktion kann über diesen Zeiger auf das Datum-struct aus der main zugreifen und dieses verändern. Das ist auch das was du hier tun willst.
Wenn du nun aber in der eingabe-Funktion deiner Zeigerkopie mittels des malloc ein neues Datum-struct zuweist, dann wird durch die folgende Eingabe dieses neue Objekt verändert. Und die main-Funktion bekommt davon auch nichts mit, weil du einen interne Kopie des übergebenen Zeigers in deiner Eingabefunktion verändert hast.
Und wenn du aus der eingabe-Funktion zurückkehrst, dann ist auch jegliche Referenz auf dieses mit malloc erzeugte struct verloren gegangen, so dass dein Programm nicht nur nicht funktioniert, sondern zudem ein Speicherleck hat, weil du keinen Zeiger mehr auf den Speicherbereich hast, um ihn mit free freizugeben.
-
Prinzipiell ist die gezeigte Herangehensweise schon mal besser als die übliche der Anfänger, denn: der aufrufende Kontext (hier main) stellt den Speicherbereich für die Nutzdaten bereit, die Funktion kümmert sich dann nur noch um den eigentlichen (fachlichen) Anwendungsfall. Wenn zu Zeiger üben willst dann also in etwa:
int main() { Datum *datZeiger = malloc(sizeof(*datZeiger)); eingabe(dat); ausgabe(dat); free(datZeiger); return 0; } void eingabe(Datum *dat) { printf("Tag: "); scanf("%d", &dat->tag); printf("Monat: "); scanf("%d", &dat->monat); printf("Jahr: "); scanf("%d", &dat->jahr); }
-
Besten Dank, werde mich noch ordentlich reinfuchsen um den Umgang wirklich "perfekt" zu beherrschen.