Referenz + ifstream + >> = Problem



  • Hi!

    Ich bin am verzweifeln!
    Ich habe eine Datei mit einer globalen ifstream-Variable (geöffnet, nicht eof
    usw) und der Funktion GetIn() die nur eine Referenz auf diese globale ifstream-Var zurückgibt.

    Jetzt kommt's:
    Schreibe ich in einer anderen Datei folgenden Code:

    ifstream in("etc/config.txt");
    string str;
    uint width;
    in >> str;
    in >> width;
    

    Geht das fehlerlos! (width wird nicht binär gespeichert, sondern als string)

    Mache ich daraus:

    ifstream& in = GetIn();
    string str;
    uint width;
    in >> str;
    in >> width;
    

    Wird der String fehlerfrei ausgelesen, nur beim Lesen von width schmiert er ab 😮

    Mache ich was falsch?



  • Kommt ne Fehlermeldung oder is einfach nur ende?



  • Vermutlich Endlosschleife -> 99% CPU-Nutzung



  • GetIn() und die globale Variable liegen in ner anderen Übersetungseinheit und die globale var ist noch nicht konstruiert, weil du in der abstrürzenden übersetungseinheit GetIn im Konstruktor einer globalen Variablen verwendet hast, um die Config als globale Variable den anderen Übersetungseinheiten zur verfügung zu stellen?

    mach dann entweder die globale variable so, daß sie vor den anderen globalen variablen konstruiert wird mit dem trick, den cin verwendet (kosten: eine variable pro übersetungseinheit) oder nen myers-singleton in GetIn (kosten: ein oder 2 takte pro GetIn), womit ich meine, du sollst die globale variable nicht mehr global machen, sondern lokal und static in GetIn. dann wird sie erzeugt, sobald sie gebraucht wird (und beim msvc evtl nicht weggeworfen, was bei nem eingabestream nicht so schlimm ist).



  • ifstream& GetIn(void)
    {
        static ifstream in("etc/config.cfg");
        if(!in.good())
            cout << "Jetzt schon fehlerhaft" << endl;
        return in;
    }
    
    //andere datei
    
    void window::Read(void)
    {
        ifstream in = GetIn();
        string tmp;
    
        in >> tmp;
        if(!in.good())
            cout << "Not good nach dem Lesen von tmp" << endl;
    
        in >> width;
        if(!in.good())
            cout << "Not good nach dem Lesen von width" << endl;
    

    Programmausgabe:
    Not good nach dem Lesen von width
    Jetzt schon fehlerhaft

    Das wird immer verwirrender! Warum kommt die Ausgabe in einer flaschen
    Reihenfolge??
    Ich benutze g++ 3.2 und Suse Linux 8.1 Pro, falls das hilft.
    😞 😞



  • ifstream in = GetIn();
    da fehlt gleich ein & vorm in.



  • Das ist eigentlich auch da, habe ich beim übertragen vergessen.



  • Nachschlag:

    Beim ersten Aufruf, klappt alles. good() liefert zwar false zurück,
    aber die Daten stimmen.
    Beim zweiten Aufruf in einer anderen Datein und Klassen klappt nichts
    mehr. Endlosschleife!

    Ich bin kurz davor zu den guten alten C-Streams zurückzukehren,
    die waren wenigstens durchschaubar.

    [ Dieser Beitrag wurde am 18.05.2003 um 02:36 Uhr von Kane editiert. ]



  • dann seh ich keinen fehler.
    mysteriös!



  • Kann es sein, das die STL/g++ bei Linux noch "etwas" buggy ist?



  • einen hab ich noch:
    ist GetIn() inline?

    probier auch mal testhalber, GetIn in die selbe Übersetzungseinheit zu nehmen wie window::Read. also dann kann gar nix schief gehen.



  • GetIn ist nicht inline. Ich habe jetzt noch ne for-Schleife reingesetzt die
    ein bißchen rechnet. AFAIK machen Compiler solche Funktionen dann aus Prinzip net inline.

    Aber trotzem:
    GetIn ist in window.cpp, er schmiert bei input.cpp ab (in input.cpp erfolgt der 2. Aufruf)

    GetIn ist in input.cpp, er schmiert bei input.cpp ab, window.cpp geht

    Ich habe jetzt mal ein Test-Projekt angelegt und da funzt es soweit!
    😮



  • Kann es sein, das der Make-File falsch ist,
    oder das ich irgendwo ungewollt in Speicher manipulieren und das nur
    Folgeerscheinungen sind? Ich bin jetzt echt am verzweifeln



  • Original erstellt von Kane:
    GetIn ist nicht inline. Ich habe jetzt noch ne for-Schleife reingesetzt die
    ein bißchen rechnet. AFAIK machen Compiler solche Funktionen dann aus Prinzip net inline.

    inline stände sie in nen header, und das wäre ungut. aber hier nicht das problem.
    for reinmachen, das sagt ja nix. wenn das for keine ausgabe erzeugt, kanns wegoptimiert sein.

    Aber trotzem:
    GetIn ist in window.cpp, er schmiert bei input.cpp ab (in input.cpp erfolgt der 2. Aufruf)
    GetIn ist in input.cpp, er schmiert bei input.cpp ab, window.cpp geht

    Also immer beim 2. Aufruf von GetIn(), wenn ich recht verstehe.

    ja, ungewollt in Speicher manipulieren ist auch mein nächster gedanke.
    leg also den dream woanders hin!

    ifstream& GetIn(void)
    {
        static ifstream* in=new ifstream("etc/config.cfg");
        if(!in->good())
            cout << "Jetzt schon fehlerhaft" << endl;
        return ∈
        //delete ist für mädchen
    }
    


  • Yeah! Geht.... 😃

    Volkard, du hast echt ein paar geile Tricks drauf 🕶

    Ich denke das mit dem Speicherdings kriege ich schon hin.
    Nehm erstmal chronologisch alles raus, was ich so eingefügt habe
    (vor 3 Tagen lief nämlich noch alles)

    Thx!


Anmelden zum Antworten