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 water

    fo::get_write_file_pointer(*fp, filename[])
    0 - fp == NULL
    6685040 - &*fp
    'file1.txt' - filename
    6687228 - &*fp
    0 - Get write file pointer

    6685040 - &*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 characterwise

    6685040 - &*fp
    fo::close_stream(*fp)
    0 - fp == NULL
    6685040 - &*fp
    1 - fp == NULL
    0 - Close stream

    6685040 - &*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 👍


Anmelden zum Antworten