Speicherschutzverletzung geschachtelten structs
-
Hallöchen,
in einem Projekt von mir nutze ich eine (?) anonyme struct, in der sich wiederum eine anonyme struct befindet, die dann schließlich den eigentlichen Inhalt enthält.
Kompilieren tut das wunderbar, aber bei der Ausführung brichts immer mit dem schönen Fehlercode 0xC000000005 ab.
Habe mal zur Veranschaulichung ein kleines Programm dazu geschrieben:
#include <iostream> using namespace std; struct { struct { char data[4]; } innerStruct; } *outerStruct; int main() { outerStruct->innerStruct.data[0] = 'a'; return 0; }Die Struktur der struct ist exakt so wie in meinem eigentlichen Projekt (erst Pointer, dann normaler Zugriff und dann char-Array) und auch in diesem Testprogramm krieg ich eine Speicherschutzverletzung.
Wo hab ich da den Denkfehler?
-
Hallo,
Du hast ja für deine struct outerStruct auch keinen Speicher reserviert. Warum ist das ein Zeiger?
-
outerStruct ist ein Null-Zeiger.
-
Dann darfst du ihn auch nicht dereferenzieren.
-
Du musst eben schon für dein Objekt Speicher reservieren wenn du es auf den Heap packen willst. Einen uninitialisierten Zeiger bzw einen auf Null zu dereferenzieren hat ein undefiniertes Verhalten zu Folge, wie du bei dir ja siehst;-)
null_zeiger schrieb:
outerStruct ist ein Null-Zeiger.
Ne ist es eigentlich nicht, dazu müsste man ihm schon 0 zuweisen. Allerdings ist auch dann undefiniertes Verhalten angesagt, es macht also im Endeffekt keinen Unterschied, nur dass man erkennt dass er noch auf nichts verweist und daher nicht dereferenziert werden sollte.
Lg freeG
-
Doch, es ist ein Nullzeiger. Variablen mit static storage duration werden automatisch null-initialisiert.
-
fr33g schrieb:
Ne ist es eigentlich nicht, dazu müsste man ihm schon 0 zuweisen.
Manche Compiler setzten uninitialisierte Zeiger im Debugmodus auf 0. So gesehen könnte es auch ein Nullzeiger sein. Allerdings sagt ja schon die Fehlermeldung das es nicht so ist.
seldon schrieb:
Doch, es ist ein Nullzeiger. Variablen mit static storage duration werden automatisch null-initialisiert.
Kannst du mir die Stelle im Standard zeigen wo das steht?
-
Nicht aus dem Standard, sondern aus dem Standardbuch:
Bjarne Stroustrup schrieb:
...wird jede Variable, die außerhalb einer Funktion definiert ist ([...]), vor dem Aufruf von main() initialisiert. [...] Falls eine solche Variable keinen expliziten Initialisierer hat, wird sie standardmäßig auf den Default ihres Typs initialisiert. Der Default-Initialisierer für eingebaute Typen und Aufzählungen ist 0.
-
Ja gut das stimmt, Variabeln von internen Datentypen die außerhalb einer Funktion( also global ) deklariert wurden, werden automatisch mit 0 initialisiert. Wusste blos nicht dass dies auch für Zeiger gilt, was aber eigentlich ja auch logisch ist.´
Auf jeden Fall ändert dies ja nichts am undefinierten Verhalten. Wenn der Zeiger aber in der main() deklariert wird, dann is er uninitialisiert.Lg freeG
Edit: Und meistens deklariert man ja einen Zeiger erst dann wenn man ihn braucht und initialisiert ihn dann auch. Sofern man überhaupt Zeiger nutzt, was ja nicht soo oft nötig ist, mal abgesehen von virtueller Polymorphie. Generell würd ich Zeiger sofort initialisieren und falls nicht einfach generell mit = 0 initialisieren( denn es kommt ja sehr selten vor dass das außerhalb einer Funktion geschieht und wenn doch macht ein = 0 ja auch nix aus ) damit man wenigstens weiß dass man ihn besser nicht dereferenzieren sollte.
-
Mh... dachte man könnte an der Stelle auch einfach einen Zeiger auf die anonyme struct erzeugen anstelle eines Variablennamens. Aber nagut, dann muss ichs doch anders machen
