Strukture als Rückgabewert einer Funktion ?!?



  • Hallo,

    unter http://www.galileocomputing.de/openbook/c_von_a_bis_z/c_017_003.htm#RxxobKap017003040029AA1F04418C
    habe ich das folgende Listing gefunden:

    /* struct4.c */
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 30
    struct adres {
       char vname[MAX];
       char nname[MAX];
       long PLZ;
       char ort[MAX];
       int geburtsjahr;
    };
    /* Funktion zur Ausgabe des Satzes */
    void ausgabe(struct adres *struct_ptr) {
       printf("\n\nSie gaben ein:\n\n");
       printf("Vorname.........:%s",struct_ptr->vname);
       printf("Nachname........:%s",struct_ptr->nname);
       printf("Postleitzahl....:%ld\n",struct_ptr->PLZ);
       printf("Ort.............:%s",struct_ptr->ort);
       printf("Geburtsjahr.....:%d\n",struct_ptr->geburtsjahr);
    }
    struct adres *eingabe(void) {
       static struct adres *adressen;
       adressen = (struct adres *)malloc(sizeof(struct adres));
       printf("Vorname : ");
       fgets(adressen->vname, MAX, stdin);
       printf("Nachname : ");
       fgets(adressen->nname, MAX, stdin);
       printf("Postleitzahl : ");
       do {scanf("%ld",&adressen->PLZ);} while(getchar()!= '\n');
       printf("Wohnort : ");
       fgets(adressen->ort, MAX, stdin);
       printf("Geburtsjahr : ");
       do {
          scanf("%ld",&adressen->geburtsjahr);
       }while(getchar()!='\n' );
       return adressen;
    }
    int main(void) {
       struct adres *adresse1, *adresse2;
       adresse1=eingabe();
       adresse2=eingabe();
       ausgabe(adresse1);
       ausgabe(adresse2);
       return EXIT_SUCCESS;
    }
    

    Jetzt meine Frage : geht denn das auf Dauer gut wenn ich den Speicher auf diese Art und Weise alloziiere ? Hier in dem Beispiel wird doch bei jedem Aufruf der Funktion eingabe neu Speicher angelegt, aber nicht mehr freigegeben ... hier ist doch ein Hund begraben ... oder übersehe ich was ?

    Wie sähe eine richtige Lösung aus ?
    würde es reichen wenn ich das folgendermaßen ergänze ?

    struct adres *eingabe(void) {
       static struct adres *adressen;
    
       if (adressen != NULL) free(adressen);
       adressen = (struct adres *)malloc(sizeof(struct adres));
    

    Grüße jesus



  • Für die Freigabe des Speichers mußt du natürlich auch noch sorgen (das kann nur das Hauptprogramm machen). Du kannst aber gerne deine Version mit dem static Pointer ausprobieren 😉 (dürfte das Ergebnis haben, daß jede Eingabe im selben Speicher schreibt und deshalb die vorherigen Adressen überschreibt)



  • (char)jesus schrieb:

    Jetzt meine Frage : geht denn das auf Dauer gut wenn ich den Speicher auf diese Art und Weise alloziiere ?

    nein. Jedenfalls ist die Wahrscheinlichkeit, dass es schiefgeht recht hoch.

    Hier in dem Beispiel wird doch bei jedem Aufruf der Funktion eingabe neu Speicher angelegt, aber nicht mehr freigegeben

    das ist schlecht, in der Tat.

    ... hier ist doch ein Hund begraben ... oder übersehe ich was ?

    jein, bei diesen geringen Mengen an Speicher, die da angefordert und nicht mehr freigegeben werden, ist es egal. Zumal ein modernes OS selbstständig den ganzen allozierten Speicher freigibt. Ein Problem hast du halt, wenn dein Programm länger läuft.

    Wie sähe eine richtige Lösung aus ?
    würde es reichen wenn ich das folgendermaßen ergänze ?

    Nein, denn du löschst "adresse1" beim erzeugen von "adresse2", was wiederum in einem blödsinnigen Verhalten resultiert, wenn du "adresse1" ausgeben willst.

    edit: too slow

    MfG

    GPC



  • Na ja ... ich teste den Tipp mal gerade ohne wild speicher freizugeben, also ohne free(adressen) und soweit ich das beurteilen kann ich der Speicherbedarf meines Programms konstant ... aber klar ist mir das nicht so richtig ...

    Grüße jesus



  • Ein Problem hast du halt, wenn dein Programm länger läuft.

    Das ist der Punkt warum ich die Frage stelle ... ich habe ein Programm, dass lange bis sehr lange läuft und dabei solche Funktionsaufrufe mehrere tausend bis sehr viele tausend Male machen soll ... ich glaube ich werde das nochmla umschreiben so dass ich die Adresse in de geschrieben wird von vornherein anlege und mit übergebe ... scheint mir das sicherste ...

    Grüße jesus

    edit: das mit den adressen ist ja nur das beispiel ... real hantiere ich mit molkulardynamiksimulationen ...



  • (char)jesus schrieb:

    Ein Problem hast du halt, wenn dein Programm länger läuft.

    Das ist der Punkt warum ich die Frage stelle ... ich habe ein Programm, dass lange bis sehr lange läuft und dabei solche Funktionsaufrufe mehrere tausend bis sehr viele tausend Male machen soll ...

    Wie wär's, wenn du, sobald du Speicher anforderst, den zentral registrierst? Oder vllt. gleich ein Speicherpool? Dann musst du nur ein mal freigeben...

    MfG

    GPC



  • wie waers mit ner kompilierten sprache mit garbage collector?
    es gibt GCs auch fuer C, aber ich wuerd eher gleich ne andere sprache nehmen, wenn ich mit speicher nichts zu tun haben will.


Anmelden zum Antworten