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 fehlerhaftDas 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 gehtAlso 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!