Hallo,
habe zwei kleine Funktionen geschrieben, die aus dem main aufgerufen
werden:
int main(void)
{
int *m, *n;
double *arrayzeiger;
einlesen (m, n, arrayzeiger);
ausgeben (m, n, arrayzeiger);
return (0);
}
void einlesen (int *m, int *n, double *arrayzeiger)
{
int temp;
char Dateiname[50];
FILE *Datei;
printf ("bitte Dateinamen eingeben\n");
scanf ("%s", Dateiname);
Datei = fopen (Dateiname, "r");
if (Datei == NULL)
{
printf ("Datei nicht gefunden\n");
exit (1);
}
fscanf (Datei, "%i", m);
fscanf (Datei, "%i\n", n);
ZV_c = (double*) malloc (n sizeof (double*));
for (temp= 0; temp< *n; temp++)
{
fscanf (Datei, "%lf\n", &arrayzeiger[temp]);
}
fclose (Datei);
}
void ausgeben (int *m, int *n, double *arrayzeiger)
{
int temp;
for (temp= 0; temp< *n; temp++)
{
printf ("nachher: = %lf\n", arrayzeiger[temp]);
}
}
Die einlesen Funktion holt sich aus der Datei die Größe des Arrays und
belegt anschließend mittels malloc Speicher fürs das Array.
Das Problem ist nur, dass mir die Funktion nicht den neuen Zeiger von
malloc zurückgibt, der also nur lokal existiert :=(
Deshalb habe ich den Aufruf der Funktion auch schon mal zu
&(*arrayzeiger) verändert, womit ich ja eigentlich die Adresse des
Zeigers in die Funktion bekommen sollte. Aber das klappt auch nicht.
Wie macht man das richtig?
Gruß,
Mark
P.S. Wenn ich den Speicher mit malloc schon vorher im main reserviere
geht alles gut (da der Zeiger ja auch nicht verändert wird).
Es ist sowieso Zufall, dass das Programm funktioniert. Du speicherst in
der Zeile "fscanf (Datei, "%lf\n", &arrayzeiger[temp]);" wegen der
uninitialisierten Variable arrayzeiger irgendwo im Speicher.
Einlesen könnte den allozierten Speicher als Pointer an Main
zurückgeben. Und am Ende von main() (oder bei neuem Aufruf von
einlesen()) kannst du den per free() auch wieder freigeben.
Eigentlich dürfte noch weniger funktionieren...
da die Zeiger alle uninitialisiert sind d.h. wenn einlesen in main
aufgerufen wird, bekommt einlesen irgendetwas nur keine Zeiger auf
benutzbare Variablen in denen die neuen Werte gespeichert werden
könnten.
Soll arrayzeiger nach dem Aufruf auf den angeforderten Speicher zeigen,
muss einlesen entweder den neuen Zeiger zurückliefern (double*
einlesen(int* m, int* n) oder man übergibt einen Zeiger auf einen
Zeiger.
Hallo,
vielen Dank für die schnelle Rückmeldung. Nun bleibt noch ein Problem:
später sollte die Funktion mehrere Arrays einlesen, d.h. ich müstte auch
mehrere Zeiger zurückgeben. Aber wenn ich erst mal weiß wie ich die
Zeiger korrekt in die Funktion ein/übergeben bekomme, dann probliere ich
da erst mal weiter und melde mich evtl. noch mal.
Danke,
Mark
void ausgeben (int m, int n, double **arrayzeiger)
36
int temp;
37
for (temp= 0; temp< *n; temp++)
38
{
39
printf ("nachher: = %lf\n", arrayzeiger[temp]);
40
}
41
42
int main(void)
43
{
44
int m, n;
45
double *arrayzeiger = NULL;
46
einlesen (&m, &n, &arrayzeiger);
47
ausgeben (m, n, &arrayzeiger);
48
//free (*ZV_c); // <== schlägt immer fehl
49
return (0);
50
}
geändert. Nun läuft es (mal wieder), aber die free Aufrufe scheitern
(bzw. der letzte auf jeden Fall, bei dem in der einlesen Funktion bin
ich mir unsicher). Insofern nehme ich stark an, dass da mmer noch was
nicht stimmt. Warum der letzte free Aufruf scheitert wundert mich, das
das main ja jetzt den in arrayzeiger die Position/Adresse des
eigentlichen Arrays hat.
Werde da wohl noch mal ne Nacht drüber schlafen müssen... Muss gestehen,
so richtig klar ist mir das leider noch nicht.
Mark
Das free in einlesen ist soweit richtig, dafür das free in main nicht.
Die Funktion ausgeben dürfte auch nur falsche Werte ausgeben, ausser
arrayzeiger[temp] wäre ein Tippfehler und sollte *arrayzeiger[temp]
sein.
arrayzeiger[temp] wäre nur dann richtig, wenn auch nur ein einfacher
Zeiger übergeben werden würde. So wie es jetzt da steht würde der tempte
(nicht vorhandene Zeiger auf einen double Zeiger) ausgewertet.
Zur Verdeutlichung:
> double* array1 = (double *)malloc(sizeof(double) * 4);
Den Rückgabewert von malloc sollte man nicht casten. Der Cast ist
unnötig und verdeckt potentielle Fehler.
Rolf Magnus wrote:
>> double* array1 = (double *)malloc(sizeof(double) * 4);>> Den Rückgabewert von malloc sollte man nicht casten. Der Cast ist> unnötig und verdeckt potentielle Fehler.
In C++ ist dieser Cast zwingend nötig. In C nicht...
Hallo,
habe nun alles soweit ohne Fehler am laufen, nur das letzte free
bereitet mir nach wie vor noch Kopfzerbrechen. Meiner Meinung (und dem
C-Buch Beispiel) nach sollte ein
[...]
ausgeben (m, n, &arrayzeiger;
if (ZV_c != NULL)
{
free (arrayzeiger);
}
return (0);
}
richtig sein. Das fliegt mir aber immer noch um die Ohren. Da ich
gelesen habe, dass nach Terminierung des Programms der Speicher eh
wieder freigegebn wird, hat das jetzt Zeit bis morgen. Werde da noch mal
ein paar Dinge ausprobieren. Ist zwar mit Sicherheit kein sauberer
Programmierstil, aber das zählt ja zum Glück auch nicht...
Bis hierhin: vielen Dank für eure Hilfe, habe wieder was dazugelernt und
steige da (so langsam) durch.
Mark