New? Nicht new?
-
Folgendes Problem:
Ich habe die Klasse GameItem.
GameItem-Klasse:
class GameItem { private: RECT srcRect; vector<string> actions; string name; public: bool useOnce; void SetName(string name) { this->name = name; } string GetName() { return name; } void SetSrcRect(RECT r) { this->srcRect = r; } RECT GetSrcRect() { return this->srcRect; } void Use(ScriptHandler* sh); void AddAction(string action) { this->actions.push_back(action); } vector<string> GetActions() { return this->actions; } void SetActions(vector<string> actions) { this->actions = actions; } bool GetUseOnce() { return useOnce; } void SetUseOnce(bool b) { useOnce = b; } };Die Daten dafür werden aus einem File gelesen.
Vor dem Lesen habe ich ein simples, temporäres GameItem:GameItem tmpItem;*plop*
So, nun setze ich dessen Attribute und pack's in einen vector.
Alles wunderbar. Nun musste ich aber der GameItem-Klasse noch
einen bool "useOnce" hinzufügen. Dieser bool wird aber nicht richtig
gesetzt, daher habe ich das mal mit "tmpItem.useOnce = false;" getestet.
Und siehe da, noch bevor die nächste Zeile ausgeführt wird,
ist useOnce dennoch wieder auf true.Wenn ich GameItem nun mit Pointer und new mache, funktioniert das Ganze
wunderbar. Möcht ich aber nicht wirklich. ;P
Also... Da so ähnliche new/nicht new-Probleme schon öfters bei mir aufgetaucht
sind, wollte ich fragen:Was zum heiligen Dreizackenfleisch habe ich da in den Grundlagen übersehen?
Was macht new mit meinem bool? Wieso funktionierts damit und ohne
new nicht? Vorher hat's auch ohne new wunderbar mit allem funktioniert.
Nur "useOnce" will nicht wirklich.
-
Es ist wahrscheinlich, dass du irgendwo eine "unsichere" Aktion ausführst, zum Beispiel mit Zeigern in falschen Bereich schreibst oder Arraygrenzen überschreitest. Dass die Bool-Variable auf dem Stack nicht funktioniert, aber auf dem Heap schon, könnte daran liegen, dass sie auf dem Heap eine andere Adresse erhält und dann zufälligerweise nicht betroffen ist. Das impliziert auch, dass dein Problem nicht verschwunden ist, wenn du dynamischen Speicher allozierst, sondern nur nicht mehr sichtbar - vielleicht passiert dann an einem anderen Ort etwas Undefiniertes.
Schau auf jeden Fall mit einem Debugger, was zwischen der Zuweisung der Bool-Variable und dem Code ein paar Zeilen weiter passiert.
-
Herzlichen Dank für die schnelle Antwort.
So etwas dürfte es eigentlich nicht geben... Aber
ich werde mal genau nachschauen.Das Seltsame ist:
tmpItem.useOnce = false; // Erste action oder End-Tag lesen getline(iStr, tmpStr);Nach dem Setzen auf false ist sie direkt wieder true.
Bereits bei getline.Sollte es so sein, wie Du sagst, habe ich ein grösseres Problem.
Die Ursache bei sowas zu finden wäre... naja, ich hätte nicht wirklich
eine Ahnung...
-
Asmodiel schrieb:
Sollte es so sein, wie Du sagst, habe ich ein grösseres Problem.
Die Ursache bei sowas zu finden wäre... naja, ich hätte nicht wirklich
eine Ahnung...Ja, solche Fehler sind meistens am schwierigsten zu finden. Da muss man meistens ein bisschen ausprobieren, einige Anweisungen weglassen, etc. Geh mit dem Debugger trotzdem schrittweise durch (in möglichst kleinen Schritten) und fange direkt bei der Zuweisung an (z.B. durch einen Haltepunkt). Dann wirst du sehen, wo genau der Fehler passiert.
Du arbeitest nicht mit mehreren Threads, oder?
-
Ok. *debug*
Gut, was Seltsames.Ergebnis (ohne new):
Release:
Schon zu Beginn ist useOnce true. Wird im Konstruktor auf false gesetzt.
(string und vector werden ebenfalls initialisiert.)
Ist danach aber noch immer true.Debug:
useOnce wird auf false gesetzt. Kann dann auch verändert werden.
Funktioniert einwandfrei.Release vs. Debug?
Was zum....Nein, verwende nur einen Thread.
-
Asmodiel schrieb:
Release vs. Debug?
Was zum....Der Debug-Modus ist generell vorsichtiger, beispielsweise werden Variablen mit 0 initialisiert. Im Forum gibts auch Beiträge dazu, möglicherweise liegt der Fehler da...
Asmodiel schrieb:
Schon zu Beginn ist useOnce true. Wird im Konstruktor auf false gesetzt.
(string und vector werden ebenfalls initialisiert.)
Ist danach aber noch immer true.Wann danach? Im Konstruktorrumpf? Oder erst nach der Konstruktion?
Benutz doch die Konstruktor-Initialisiererliste für solche Dinge.Und bist du den Code jetzt in ganz kleinen Schritten durchgegangen, sodass du genau feststellen kannst, wo sich der Wert ungewollt ändert?
-
erm... im Release Modus fehlen die Debug-Informationen, die im Debug Modus mit rein kompiliert werden...
das heißt, es kann auch sein, dass im Debugger beim ausführen der Release-Version auch 42 in deiner boolschen Variable stehen kann.
Macht aber nix, weil dus vermutlich nicht siehst, oder eventuell was falsches siehst.
-
Es lag wirklich daran, dass im Release
nicht der wirkliche Wert drin stand.
Ich habe vergessen, den Wert beim Kopieren
zu setzen.Und da beim Debuggen in der Release-Version nicht
der wirkliche Wert angezeigt wurde, dachte ich, ich könne
den Wert gar nicht erst verändern.Vielen Dank für die Hilfe, und Verzeihung wegen der Zeitverschwendung.
Dennoch konnte ich einiges lernen, also herzlichen Dank für die Beiträge.
-
Asmodiel schrieb:
Vielen Dank für die Hilfe, und Verzeihung wegen der Zeitverschwendung.
Kein Problem, solche Dinge treten bei mir die ganze Zeit auf
