Problem mit Feld von Strukturen
-
int main(int argc, char* argv[]) { struct bla { int x; }; bla* foo[50]; foo[22]->x = 200; }Sinngemäß ist das mein Code, nun funktioniert das compilieren einwandfrei, beim Ausführen bricht es aber sofort ab.Mein Compiler gibt mir nur "Process terminated with status 3" zurück. Ich benutze Windows XP und Code::Blocks, mit MinGW.
Könnte mir bitte jemand helfen, und mir erklären was ich falsch mache :)?
MfG.
-
strukturen? schrieb:
Könnte mir bitte jemand helfen, und mir erklären was ich falsch mache :)?
Du erzeugst 50 Zeiger auf
bla. Diese 50 Zeiger zeigen ins Nirvana. Jetzt nimmst du den 23. Zeiger, welcher wie alle anderen eben irgendwohin zeigt, dereferenzierst ihn und weist dem Objekt 200 zu, in einem Speicherbereich der dir nicht gehört.Absolutes undefiniertes Verhalten. Deine Festplatte hätte theoretisch sogar gelöscht werden können

Korrekt wäre wohl hier eher das:
int main(int argc, char* argv[]) { struct bla { int x; }; bla foo[50]; // kein bla* foo[22].x = 200; // kein Zeiger, sondern Objekt, also . und nicht -> }Grüssli
-
Du deklarierst einen Zeiger, der zeigt aber auf keinen Speicherbereich!
Einbla *foo[50]; for(int i = 0; i < 50; i++) { bla temp; foo[i] = new bla; // oder auf dem Stack ohne delete: foo[i] = &temp; } foo[22]->x = 200; delete [] foo;schafft z.B. Abhilfe.
-
@Ad aCTa,
Auch sehr schönes undefiniertes Verhalten. Du gibst automatischen Speicher frei und löschst allerdings den dynamischen Speicher nicht.
Richtig wäre bei deinem Beispiel:int main(int argc, char* argv[]) { struct bla { int x; }; bla* foo[50]; for(int i = 0; i < 50; i++) { foo[i] = new bla; } foo[22]->x = 200; // nicht delete[], sondern jedes einzelne Objekt. for(int i = 0; i < 50; i++) { delete foo[i]; } }Und das mit dem
bla temp;auf dem Stack ist auch undefiniert, da das Stackobjekt bei jedem Schleifendurchlauf neu erstellt, bzw. zerstört, wird. Ausserhalb der Schleife ist kein Objekt mehr vorhanden. Also auch ein Zugriff auf Speicher, welcher dir nicht mehr gehört.Grüssli
-
Danke für die schnelle, gut verständliche Hilfe :).
-
Da es gerade passt: Was würde bla* foo = new[] bla; gewirken?
Und was bla* foo = new bla[];?
-
gleich_hinterher schrieb:
Da es gerade passt: Was würde bla* foo = new[] bla; gewirken?
Und was bla* foo = new bla[];?Ersteres einen Syntaxfehler.
Beim zweiten bin ich mir nicht ganz sicher. Soviel ich weiss, wird da ein Feld mit der Grösse 0 angelegt, also ist die Aktion meistens sinnfrei.Edit: Laut meiner Memory-Überwachungs-Klasse wird da tatsächlich
operator new[]mit 0 Byte als Argument aufgerufen.Edit 2: Jetzt wäre natürlich noch interessant zu wissen, ob man ein Memory Leak hat, wenn man diesen Speicher nicht mehr freigibt. Laut meiner Klasse ja, und zwar mit der Grösse von 0 Byte. :p
Aber freigeben ist wohl sicherer. Zumal der Fall ja so oft vorkommt.