FILE Pointer als Parameteruebergabe geht nich
-
Hallo,
heute hab ich folgendes Problem mit den Filestreams, oder eher mit der Uebergabe by-Reference?! Ich habe eine Funktion die einen Filepointer erzeugt (FILE* als Parameter), eine Funktion, die einen Text in das File schreibt und eine Funktion die den FILE* wieder schliesst. Das File wird erzeugt, aber es wird nichts hineingeschrieben.Seltsam ist imo dass die Adressen des erzeugten Speichers fuer den lokalen FILE* in der Filepointerfunktion (get_write_file_pointer()), 6687228, und die im weiteren Verlauf benutzte Adresse auf die das in der main() verwendte FILE* zeigt, 6685040, verschieden sind. Anscheinend wird in der ersten Funktion Speicher fuer den dortigen lokalen FILE* erzeugt, und irgendwie wieder verworfen.
1. Warum habe ich hier verschiedene Adresse, es sollte doch ein pass-by-reference sein bei dem der Zeigerinhalt direkt uebergeben wird, bzw der Zeiger der Aufrufe-Funktion von der aufgerufenen Funktion auch veraendert werden kann?
2. Ist das ein Speicherleck, woran liegt dieses Verhalten?
3. Wie bekommt man die Funktionen nun zum laufen?
#include <string.h> #include <stdlib.h> #include <stdio.h> #define DEBUG int get_write_file_pointer(FILE* fp, char filename[FILENAME_MAX]) { #ifdef DEBUG printf("\tfo::get_write_file_pointer(*fp, filename[])\n"); printf("\t%i - fp == NULL\n", (fp == NULL)); printf("\t%i - &*fp\n", &*fp); printf("\t\'%s\' - filename\n", filename); #endif fp = NULL; if(filename == NULL) return -1; if( (fp = fopen(filename, "w")) == NULL){ fprintf(stderr, "fo::get_write_file_pointer(FILE*, char[]) - Failed!\n"); return -1; } #ifdef DEBUG printf("\t%i - &fp\n", &fp); #endif return 0; }; int write_char(FILE* fp, char* content) { #ifdef DEBUG printf("\tfo::write_char(*fp, *content)\n"); printf("\t%i - fp == NULL\n", (fp == NULL)); printf("\t%i - &*fp\n", &*fp); printf("\t\'%s\' - content\n", content); #endif if(fp == NULL) return -1; if(content == NULL) return -1; int c; while( (c=*content++) != '\0') putc(c, fp); return 0; }; int close_stream(FILE* fp) { #ifdef DEBUG printf("\tfo::close_stream(*fp)\n"); printf("\t%i - fp == NULL\n", (fp == NULL)); printf("\t%i - &*fp\n", &*fp); #endif if(fp == NULL) return -1; int iRes = fclose(fp); fp = NULL; free(fp); #ifdef DEBUG printf("\t%i - fp == NULL\n", (fp == NULL)); #endif return iRes; }; int main(){ FILE* fp = NULL; char file1[] = "file1.txt"; char text1[] = "Jack and Jill went up the hill to fetch a pail of water\n"; // ... printf("%i - Get write file pointer\n", get_write_file_pointer(fp, file1)); printf("%i - &*fp\n", &*fp); // XXX printf("%i - Writing file characterwise\n", write_char(fp, text1)); printf("%i - &*fp\n", &*fp); // XXX printf("%i - Close stream\n", close_stream(fp)); printf("%i - &*fp\n", &*fp); // XXX printf("Done.\n\n\n"); // ... return 0; }
Der Output sieht in etwa so aus:
file1 = 'file1.txt'
text = Jack and Jill went up the hill to fetch a pail of waterfo::get_write_file_pointer(*fp, filename[])
0 - fp == NULL
6685040 - &*fp
'file1.txt' - filename
6687228 - &*fp
0 - Get write file pointer6685040 - &*fp
fo::write_char(*fp, *content)
0 - fp == NULL
6685040 - &*fp
'Jack and Jill went up the hill to fetch a pail of water
' - content
0 - Writing file characterwise6685040 - &*fp
fo::close_stream(*fp)
0 - fp == NULL
6685040 - &*fp
1 - fp == NULL
0 - Close stream6685040 - &*fp
Done.
-
Du willst einen FILE* "per Referenz" übergeben - also brauchst du einen Zeiger auf einen FILE*:
int get_write_file_pointer(FILE** fp, char filename[FILENAME_MAX]) { #ifdef DEBUG printf("\tfo::get_write_file_pointer(*fp, filename[])\n"); printf("\t%i - fp == NULL\n", (fp == NULL)); printf("\t%i - &*fp\n", &*fp); printf("\t\'%s\' - filename\n", filename); #endif *fp=NULL; if(filename == NULL) return -1; if( (*fp = fopen(filename, "w")) == NULL){ fprintf(stderr, "fo::get_write_file_pointer(FILE*, char[]) - Failed!\n"); return -1; } #ifdef DEBUG printf("\t%i - &fp\n", &fp); #endif return 0; }; ... FILE* file; get_write_file_pointer(&file,"test.txt");
-
Fabeltier schrieb:
Seltsam ist imo dass die Adressen des erzeugten Speichers fuer den lokalen FILE* in der Filepointerfunktion (get_write_file_pointer()), 6687228, und die im weiteren Verlauf benutzte Adresse auf die das in der main() verwendte FILE* zeigt, 6685040, verschieden sind. Anscheinend wird in der ersten Funktion Speicher fuer den dortigen lokalen FILE* erzeugt, und irgendwie wieder verworfen.
Das ist überhaupt nicht seltsam, sondern normal.
Fabeltier schrieb:
1. Warum habe ich hier verschiedene Adresse,
Weil es unterschiedliche Variablen sind.
Fabeltier schrieb:
es sollte doch ein pass-by-reference sein bei dem der Zeigerinhalt direkt uebergeben wird, bzw der Zeiger der Aufrufe-Funktion von der aufgerufenen Funktion auch veraendert werden kann?
Es ist ein Call-By-Value, denn der "Value-Typ" ist FILE*, nicht FILE. Du arbeitest ja in deinen Funktionen nirgends mit dem dereferenzierten Zeiger, sondern immer mit dem FILE* selbst. Wenn du den also in der Funktion ändern willst, musst du mit FILE** arbeiten.
-
Danke, ich dachte ich muss mehr oder weniger "FILE" by-reference uebergeben und nicht den ganzen Zeiger auf FILE*!! Super