Zeiger auf Struct als rückgabewert von Funktion ?



  • Du kannst keine Zeiger auf lokale Variablen zurückgeben.
    Du kannst sehr wohl Zeiger auf Speicher zurückgeben, den du mit malloc besorgt hast.

    struct tiere *create_tiere(int num)
    { //         ^ hier ist ein Zeiger
      struct tiere temp;  // lokale Variable (vom Stack)
      temp.tier = malloc(num * sizeof(struct Tdata));  
      return(&temp); Das geht nicht, da temp nach dem verlassen nicht mehr gültig ist
    //       ^ & wegen Zeiger
    }
    

    Der Speicher auf den temp.tier zeigt ist auch weiterhin gültig, nur kommst du da nicht mehr dran, da temp ungültig wird.



  • Vielen Dank schonmal das habe ich jetzt soweit verstanden 🙂

    Die Funktion gibt nun also einen Pointer auf den reservierten Speicherplatz zurück.

    Wie kann ich weiter vorgehen, wenn ich den reservierten Speicherplatz jetzt nutzen möchte ?

    struct tiere *get_tiere_from_file()
    {
      struct tiere *test;
      test = create_tiere(length);  
    }
    

    Das gibt nun den Fehler "Assigment makes pointer without cast"

    Wenn ich nun versuche einen cast zu machen:

    struct tiere *get_tiere_from_file()
    {
      struct tiere *test;
      test = (struct tiere*)create_tiere(length);  
    }
    

    Nun kommt "Conflicting types for 'create_tiere'" 😕



  • Welche Version von create_tiere() hast du denn jetzt?



  • struct tiere *create_tiere(int num)
    {
    struct tiere *temp;

    temp = malloc(sizeof(struct tiere));
    temp->tier = malloc(num * sizeof(struct Tdata));
    return(temp);
    }



  • Poste mal das kleinste compilierbare Program, das den Fehler verursacht.



  • #include <stdio.h>
    #include <stdlib.h>
    
    struct Tdata {
    	char *name;
    	int groesse;
    };
    
    struct tiere {
        struct Tdata *tier;   
    };
    
    struct tiere *get_tiere_from_file()
    {
      struct tiere *test;
    
      test = (struct tiere*) create_tiere(5);
    
      //return(test); 
    }       
    
    struct tiere *create_tiere(int num)
    {
      struct tiere *temp; 
    
      temp = malloc(sizeof(struct tiere)); 
      temp->tier = malloc(num * sizeof(struct Tdata)); 
      return(temp);       
    }       
    
    int main(int argc, char *argv[])
    {
      struct tiere main; 
    
    //  main = get_tiere_from_file();
    
      system("PAUSE");	
      return 0;
    }
    


  • Du verwendest eine erst nachträglich deklarierte Funktion, dafür trifft der Compiler bestimmte Standardannahmen, die bei dir schiefgehen:

    http://ideone.com/jsHd2



  • @ wutz

    stimmt so funktioniert es 🙂

    Hier mal der aktuelle Code. Ein Problem gibt es jetzt scheinbar noch. Es lässt sich nun zwar alles compilieren, allerdings stürzt das Programm ab.
    Die Probleme treten vermutlich bei enter_tier(t, i, text, size) auf.

    #include <stdio.h>
    #include <stdlib.h>
    
    struct Tdata {
    	char *name;
    	int groesse;
    };
    
    struct tiere {
        struct Tdata *tier;   
    };
    
    // Allokiert speicher fuer den Namen (size = lange des namens) 
    // eines Tieres und trŠgt das Tier an der Stelle index ein!
    void enter_tier(struct tiere *t, int index, char *name, int size)
    {
      t->tier[index].groesse = size;
      t->tier[index].name = malloc((strlen(name) * sizeof(char)) + 1);
      strcpy(t->tier[index].name, name);     
    } 
    
    // Allokiert Speicher fuer die gegebene Datenstruktur 
    // (num = Anzahl der Tiere)
    struct tiere *create_tiere(int num)
    {
      struct tiere *temp; 
    
      temp = malloc(sizeof(struct tiere)); 
      temp->tier = malloc(num * sizeof(struct Tdata)); 
      return(temp);       
    } 
    
    // Oeffnet die Datei tiere.txt und ruft die Funktionen 
    // create_tiere und enter_tier auf! 
    struct tiere *get_tiere_from_file()
    {
      char *text;
      int length, size; 
      int i = 0;    
      FILE *fp;
      struct tiere *t;
    
      fp = fopen("tiere.txt", "r");  
    
      fscanf(fp,"%d",&length);
    
      t = create_tiere(length);
    
      while(fscanf(fp, "%s%d\n",&text, &size) != EOF)
      {
        enter_tier(t, i, text, size);
        i++;
      } 
    
      for(i = 0; i < length; i++)
      {
        printf("%s %d\n", t->tier[i].name, t->tier[i].groesse);       
      }      
    
      fclose(fp); 
    
      return(t); 
    }       
    
    // gibt den gesamten Speicher am Ende des Programms wieder frei!
    void destroy_tiere(struct tiere *t, int num)
    {
      free(t->tier);
      free(t);     
    }     
    
    int main(int argc, char *argv[])
    {
      struct tiere *t; 
    
      t = get_tiere_from_file();
      destroy_tiere(t, 0);
    
      system("PAUSE");	
      return 0;
    }
    

    Inhalt der "tiere.txt":

    5
    Loewe, 120
    Gorilla, 170
    Maus, 5
    Hund, 40
    Giraffe, 450
    


  • struct tiere *get_tiere_from_file()
    {
      char *text; // Das text hat keinen Speicher wo der Text abgelegt werden kann. Da gehört ein Array hin (Oder dynamischer Speicher)
    ....
      while(fscanf(fp, "%s%d\n",&text, &size) != EOF) // Das & ist bei text falsch,
    // Egal ob text ein Zeiger oder Array ist.
    // Das ',' gehört mit zum Namen. Wenn da aber "Tier , 11" steht, hast du ein Problem
    


  • Perfekt mit einem Char array klappt es 🙂

    Gibt es eine Möglichkeit das "," direkt über die Formatierungsangabe der fscanf heraus zu filtern ?


Anmelden zum Antworten