Seltsames Problem mit struct



  • hallo,

    hab ein komisches problem mit structs.
    das struct schaut so aus:

    typedef struct structname{
           char *pointer1;
           unsigned int zahl;
           unsigned char *pointer2;
    } MY_STRUCT;
    

    danach hab ich so eine funktion:

    MY_STRUCT *funktion(char *neuer_pointer)
    {
         MY_STRUCT _s1,*s1;
         s1=&_s1;
    
         s1->pointer1=neuer_pointer; // hier ist noch alles ok;
         s1->zahl=1234; // <---
         printf("%d\n",s1->zahl); // alles ok, hier wird wie gewollt 1234 ausgegeben
         return s1;
    }
    

    und jetzt die main-funktion:

    #include <stdio.h>
    
    int main()
    {
          MY_STRUCT *test_struct=funktion("Das ist ein Test.");
    
          printf("%s\n",test_struct->pointer1); // alles ok, hier wird "Das ist ein Test" ausgegeben
          printf("%d\n",test_struct->zahl); // FELHER: oben wird zwar 1234 ausgegeben, hier aber nicht.
                                            // die zahl, die hier ausgegeben wird, scheind beliebig, es ist aber nicht 1234
    
          return 0;
    }
    

    ich versteh nicht genau wo hier der fehler ist, vielleicht könntet ihr mir weiterhelfen?



  • Lokale Auto-Variablen sind nach Verlassen einer Funktion nicht mehr gültig.

    Der Speichervon _s1 wird beim Aufruf von printf überschrieben.



  • ok, und wie lässt sich das problem lösen? pointer auf pointer?



  • a) Du definierst die struct Variable in main.
    b) Oder du besorgst den Speicher mit malloc.

    a) ist besser, da du bei b) dafür sorgen musst, dass der Speicher auch wieder freigegeben wird.

    Bei a) kannst du die struct als return-Wert nehmen oder den Zeiger an funktion() mit übergeben.



  • DirkB schrieb:

    a) Du definierst die struct Variable in main.
    b) Oder du besorgst den Speicher mit malloc.

    a) ist besser, da du bei b) dafür sorgen musst, dass der Speicher auch wieder freigegeben wird.

    Bei a) kannst du die struct als return-Wert nehmen oder den Zeiger an funktion() mit übergeben.

    wie sähe lösung a) genau aus?
    du meinst, ich soll mit malloc sizeof(MY_STRUCT) reservieren?

    wie ist das denn z.b. beim FILE struct? also FILE *datei=fopen(... das müsste doch so ähnlich sein



  • Bei a) gibt es kein malloc.

    MY_STRUCT funktion(char *neuer_pointer)
    {
         MY_STRUCT s1;
    
         s1.pointer1=neuer_pointer; // hier ist noch alles ok;
         s1.zahl=1234; // <---
         printf("%d\n",s1.zahl); // alles ok, hier wird wie gewollt 1234 ausgegeben
         return s1;
    } 
    
    int main()
    {
          MY_STRUCT test_struct=funktion("Das ist ein Test.");
    
          printf("%s\n",test_struct.pointer1); // alles ok, hier wird "Das ist ein Test" ausgegeben
          printf("%d\n",test_struct.zahl); 
          return 0;
    }
    

    fopen nimmt entweder auch malloc (und fclose dann free) oder es nutzt ein statisches Array in dem die Werte eingtragen werden.



  • sorry, ich meinte b) 🙂

    ich versteh nicht ganz, was ich da wie mit malloc reservieren soll



  • hallo! schrieb:

    sorry, ich meinte b) 🙂

    ich versteh nicht ganz, was ich da wie mit malloc reservieren soll

    Ja, du brauchst Speicher von der Größe deiner struct. und die Adresse kannst du deinem s1 zuweisen.
    statt Zeile 4 bei dir (_s1 brauchst du dann auch nicht):

    s1 = malloc(sizeof(MY_STRUCT));
    

    Aber wie gesagt ist das blödes Design weil du dann dafür sorgen musst, dass der Speicher auch wieder freigegeben wird.



  • also dann so?

    MY_STRUCT *funktion(char *neuer_pointer)
    {
         MY_STRUCT *s1;
         s1=malloc(sizeof(MY_STRUCT));
    
         s1->pointer1=neuer_pointer; // hier ist noch alles ok;
         s1->zahl=1234; // <---
         printf("%d\n",s1->zahl); // alles ok, hier wird wie gewollt 1234 ausgegeben
         return s1;
    }
    


  • hallo! schrieb:

    also dann so?

    ...
    

    Kommt drauf an woher dein neuer_pointer kommt.
    Malloc kann NULL liefern, das sollte man auf
    jeden Fall prüfen.


Anmelden zum Antworten