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!