Hallo Christof,
- Nicht initialisierte Zeiger, insbesondere als
Auto-Variablen liefern fast immer sehr „schöne“ Ergebnisse
(Der Zeiger ist dann mit Daten-Müll auf dem Stack
inizialisiert, und je nach Programm steht an dieser Stelle
immer der gleiche Schrott und das ganze ist reproduzierbar).
Keine nichtinitialisierten Zeiger.
Gestern hat es mir mal eine Weile lang ein char[255]
ueberschrieben. (nicht Zeiger auf ein char-array, sondern echt
reservierter Speicher) Als ich dann mal den Speicher mit dem
Debugger ueberwacht habe hat er aufgehoert zu ueberschreiben.
Grundsätzlich gibt es nur 3 Ursachen für einen Programmfehler:
- Bug ein deinem Source-Code.
- Bug in einem fremden Source (inkl. Compiler. Betriebssystem und Tools).
- Fehler in der Hardware.
Mit deinem anderen Posting „Speicher vor Schreibzugriffen schuetzen“ beweist du, dass es doch ein ungültiger Zeiger ist der die Probleme verursacht!
Wenn du das Programm mit dem Debugger startest, verschieben sich teilweise die Adressen, und wenn dein fehlerhafter Zeiger mit einem Festen falschen Wert arbeitet schreibt er dann in einen Bereich, welcher nicht benutzt wird und dein Programm funktioniert scheinbar fehlerfrei.
Mit gröster Wahrscheinlichkeit ligt das Problem nicht an einem Zugriff auf die „zerstörte“ Variable sondern ganz wo anders.
Ein Typisches Problem für nicht initialisierte Zeiger sind ungültige Zeiger und bei denen hat der Compiler keine Möglichkeit den Fehler zu enrkennen. z.B:
typ_Irgend_was *Igend_was;
Igend_was = new typ_Irgend_was;
Igend_was = wert;
delete Igend_was;
*Igend_was = irgend_ein_wert;
Mit „Igend_was = new typ_Irgend_was;“ wird „Igend_was“ freier Speicher zugewiesen. Nun kannst du mit „Igend_was“ alles erlaubte tun und die Speicherverwaltung garantiert dir, dass der zugewiesene Speicherbereich kein zweites mal zugewiesen wird.
Mit „delete Igend_was“ teilst du der Speicherverwaltung mit, dass der reservierte Bereich nicht mehr benötigt wird.
Du hast aber die Möglichkeit immer noch über „Igend_was“ auf den Speicherblock zuzugreifen. Wenn dieser Block nicht von der Speicherverwaltung für etwas anderes bereitgestellt wird wird auch alles, scheinbar fehlerfrei, funktionieren. Nur wenn jetzt die Speicherverwaltung diesen Speicherbereich für etwas anderes zugeteilt hat gibt es Probleme.
Um dem vorzubeugen ist es gute Praxis immer folgendes Konstrukt zu verwenden:
delete Igend_was;
Igend_was = NULL;
Hier besteht nun die Möglichkeit, dass die Laufzeitbibliothek den NULL-Zeiger erkennt und eine Fehlermeldung erzeugt.
Schwierig wird es bei folgendem Code
typ_Irgend_was *Igend_was;
typ_Irgend_was *noch_Igend_was;
Igend_was = new typ_Irgend_was;
Igend_was = wert;
noch_Igend_was = Igend_was;
delete Igend_was;
Igend_was = NULL;
*noch_Igend_was = irgend_ein_wert;
Hier nusst du aufpassen und auch die Kopie („noch_Igend_was“) mit dem NULL-Zeiger initialisieren.
MfG Peter(TOO)