pointer rückgabe -> wert ändert sich!!?!



  • hallo!

    ich habe folgendes problem:

    ich hab ne Funktion mit nem Zeiger auf Struktur
    dieser Zeiger bekommt nun ne Adresse von calloc (speicher für struct reserv.)
    dann wird die struktur eingelesen (in speicher von calloc).
    der zeiger wird nun mit return an main zurückgeben...
    doch in main zeigt der pointer nun auf eine andere adresse, und nicht mehr auf den von calloc reservierten speicher!

    kann mir jemand helfen?



  • Du übergibst eine kopie des zeigers an die funtion und änderst diesen. Im hauptprogramm ändert sich der zeiger nicht.
    lösung: übergebe einen zeiger auf den zeiger.
    K.



  • hi,

    hab nach deiner beschreibung mal das prog. geschrieben und bei mir läufts!

    #include <stdio.h>
    #include <stdlib.h>
    
    struct foo {
    	int zahl;
    	char c;
    };
    
    struct foo *fo(void);
    
    struct foo *fo(void)
    {
    
    	struct foo *wahoo;
    
    	wahoo=(struct foo *)calloc(1,sizeof(struct foo));
    
    	wahoo->zahl=1;
    	wahoo->c='a';
    
    	return wahoo;
    }
    
    int main(void)
    {
    
    	struct foo *wahoo;
    
    	wahoo=fo();
    
    	printf("%d%c\n", wahoo->zahl, wahoo->c);
    
    return 0;
    }
    

    Vielleicht postest du mal deinen code, um dem Problem auf die Schliche zu kommen!

    //EDIT:

    kemuri schrieb:

    ich hab ne Funktion mit nem Zeiger auf Struktur

    Heisst das, das deine Funktion einen Zeiger auf ne Struktur zurückgibt oder
    als Argument bekommt?

    b4sh0r



  • bei mir funktioniert das mit der übergabe wenn ich alles in einer datei hab,
    hab aber mehrere sachen auf mehrere dateien gelegt. liegts vielleicht daran?



  • perdef.h:

    #ifndef PerDef_Is_Included                         /* Steuerung bedingtes include */
      #define PerDef_Is_Included
    
      /********************************************************************************/
      /* Includes von Headerdateien                                                   */
      /********************************************************************************/
      /**/
      #include <stdio.h>                          /* Standard-Ein-/Ausgabe-Funktionen */
      #include <string.h>                                        /* String-Funktionen */
      #include <conio.h>                             /* Borland Bildschirm-Funktionen */
    
      /********************************************************************************/
      /* Vereinbarung von benannten Konstanten                                        */
      /********************************************************************************/
    
      #define DEF_FILE_NAM  "PerLis"                        /* Default-Datendateiname */
      #define DEF_FILE_EXT  ".txt"                        /* Extension der Datendatei */
    
                                                      /* Vereinbarung von Konstaneten */
      #define NAMLEN      21                          /* max. Namenslaenge + 1 ('\0') */
      #define PERANZMIN    2                                 /* minimale Personenzahl */
      #define PERANZMAX   10                                 /* maximale Personenzahl */
    
      #define EMPTYTAG_C  '$'              /* char  : Steuerzeichen Datenende im Feld */
      #define EMPTYTAG_S  "$"              /* string: Steuerzeichen Datenende im Feld */
    
      /********************************************************************************/
      /* Vereinbarung von Datentypnamen                                               */
      /********************************************************************************/
    
      typedef char nam_t [NAMLEN];                             /* Typname fuer String */
      typedef unsigned int ui_t;                         /* Typname fuer unsigned int */
    
      typedef struct gd_e {                                  /* Struktur Geburtsdatum */
                ui_t GDTag;
                ui_t GDMonat;
                ui_t GDJahr;
              } gd_t;                                        /* Typname fuer Struktur */
    
      typedef struct person_e {                                    /* Struktur Person */
                ui_t  IdentNr; 
                nam_t FNam, VNam; 
                gd_t  GebDat;
              } person_t;                                    /* Typname fuer Struktur */
    
      typedef person_t*  pperson_t;               /* Typname fuer Zeiger auf Struktur */
    
      typedef pperson_t* ppperson_t;   /* Typname fuer Zeiger auf Zeiger auf Struktur */
    
      /********************************************************************************/
    
    #endif
    

    und denn: perio.c :

    #include "PerIO.h"
    #include <stdio.h>  /*printf, scanf */
    #include <string.h> /* strings kopieren */
    #include <stdlib.h> /* calloc           */
    
    void GetFileName(char * pFileName){
    
    	char buffer[81];
    
    	// dateinamen einlesen
    	printf("\n Eingabe Dateiname (ohne Erweiterung) [Return = \"PerLis\"] : ");
    	gets(buffer);
    	// leere Eingabe Default ersetzen
    	if(buffer[0]=='\0') strcpy(buffer,DEF_FILE_NAM);
    	// .txt anhaengen
       /*buffer=*/strcat(buffer, DEF_FILE_EXT);
    	// dateinamen auf zeiger speichern
       strcpy(pFileName,buffer);
    }
    
    pperson_t ReadPerFromFile (char* dateiname,int* anz){
    
       int i;
       FILE *fp;
       char buffer[80];
       pperson_t pDaten;
    
       if(fp = fopen(dateiname, "r")){
       	fscanf(fp,"%d\n\n",anz);
          printf("anz read: %d\n",*anz);
    
          printf("read p %p\n",pDaten = (person_t*)calloc(*anz+1,sizeof(person_t)));
          gets(buffer);
    
          for(i=0;i<*anz;i++){
    	      fscanf(fp,"%d\n%s\n%s\n%d_%d_%d\n\n",
             	&(pDaten)[i].IdentNr,
                &(pDaten)[i].FNam,
                &(pDaten)[i].VNam,
             	&(pDaten)[i].GebDat.GDTag,
            		&(pDaten)[i].GebDat.GDMonat,
            		&(pDaten)[i].GebDat.GDJahr);
                printf("read p %p\n",pDaten);
          }/*for*/
          gets(buffer);
    	   strcpy(pDaten[i].FNam, EMPTYTAG_S);
       }else printf(" Fehler beim Oeffnen der Datei.\n");
       printf("read p %p\n",pDaten);
    
       return pDaten;
    }
    

    und main dann:

    #include <conio.h>	//clrscr();
    #include <stdlib.h>  //free();
    #include "PerDef.h"
    
    int main(void){
    
    	int anzahl=0,i;
    	pperson_t pDaten; //Zeiger für Person - Verwaltung
            char	dummy[81],
    		dateiname[40];
    
    	clrscr();
       printf("\n Personenverwaltung - Ausgabe\t\t\t\t\tMathias Paech\n");
       printf(" ============================\n\n");
    
       //Datei lesen
    	GetFileName(dateiname);
       pDaten=ReadPerFromFile(dateiname,&anzahl);
       printf("main p %p\n",pDaten); //HIER IS DER ZEIGER DANN NICHT MEHR WIE IM UP!
    
       printf(" [enter] ");
       gets(dummy);
    
       //dynamischen Speicher freigeben
       free(pDaten);
       return 0;
    }
    


  • //EDIT:

    kemuri schrieb:

    ich hab ne Funktion mit nem Zeiger auf Struktur

    Heisst das, das deine Funktion einen Zeiger auf ne Struktur zurückgibt oder
    als Argument bekommt?

    b4sh0r

    also er soll nen zeiger auf struktur zurückgeben



  • meine antwort war folgendermassen gemeint

    struct foo {
      int z;
      char c;
    };
    
    void makefoo( struct foo ** pf ) {
      struct foo * p;
      p = (struct foo * )malloc( sizeof(struct foo) );
      p->z = 1;
      *pf = p;
    }
    
    int main() {
      struct foo * f;
      f = 0;
      makefoo( &f );
      printf("%d\n", f->z); 
    
    }
    


  • @bashor && ZuK
    Ihr habt was wichtiges vergessen: free()!!!



  • AJ schrieb:

    @bashor && ZuK
    Ihr habt was wichtiges vergessen: free()!!!

    ich habe wenigstens eine zeile frei gelassen für

    free(f);
       return 0;
    

    😉 K.



  • ik habs jetzt umgebaut mit zeiger auf zeiger...
    aber kann man den zeiger nicht einfach per return zuweisen??

    stark vereinfach:

    up(){
       pointer=...calloc...
       return pointer;
    }
    
    main(){
       pointer=up();
    }
    


  • kemuri schrieb:

    aber kann man den zeiger nicht einfach per return zuweisen??

    Kann man auch, wie du anhand von Bashor's Beispiel siehst.



  • AJ schrieb:

    kemuri schrieb:

    aber kann man den zeiger nicht einfach per return zuweisen??

    Kann man auch, wie du anhand von Bashor's Beispiel siehst.

    ja das beispiel funzt bei mir auch! aber in dem code den ik gepostet hab, wird mir ne falsche adresse zurückgegeben!


Anmelden zum Antworten