Zeigeradresse ändert sich von allein?!?
-
Hallo,
da der original Code etwas zu viel wäre ... hier erstmal ein kleines Beispielkonstrukt, was bei meinem Originalcode leider einen Absturz nach sich zieht. Ich hoffe ich habe die wichtigsten Informationen meines Codes im Beispiel abgebildet.
Das Programm besteht aus 2 DLLs und einer EXE.Klasse aus Dll_A
class A { public: A(int param) : m_piData(NULL) { int a=param; } int* m_piData; };
Klasse aus Dll_B
class B : public A { public: B(int param) : A(9), m_iData(param), m_piData2(NULL) { int a=0; } int m_iData; int* m_piData2; };
Aufrufende Anwendung
int _tmain(int argc, _TCHAR* argv[]) { B *WhatEver = new B(5); if(WhatEver->m_piData) { // hier läuft das Programm rein, da der Zeiger WhatEver->m_piData die // Adresse 0x0123457A hat und DIESER Zeiger nicht auf NULL initialisiert // wurde. int a = *(WhatEver->m_piData); } return 0; }
Debug-Schritte:
1. Aufruf Konstruktor Klasse B
2. Aufruf Konstruktor Klasse A
3. Der Zeiger m_piData hat die Adresse 0x01234567 (Damit ist die tatsächliche Adresse des Pointers gemeint und nicht worauf er zeigt)
4. Zuweisen von NULL nach m_piData funktioniert auch einwandfrei
5. Verlassen des Konstruktors der Klasse A
6. Debugger steht nun im Konstruktor Code der Klasse B
7. Der Pointer m_piData hat nun eine andere Adresse (0x0123457A). Da dieser "neue" Pointer nicht auf NULL initialisiert ist, crashed die Applikation bei mir in der Main() Funktion.Ich hoffe mein Problem ist verstanden worden. Falls jmd. irgendeine Idee hat, woran dies liegen könnte, oder falls Euch noch irgendwelche Informationen fehlen ... sagt Bescheid.
Der Absturz erfolgt im übrigen auch nur in der Debug Version. Die Release Version läuft einwandfrei
-
Ich kann dein Problem nicht nachvollziehen.
WhatEver->m_piData
hat den Wert, mit dem du im Konstruktor von A initialisierst (also NULL). Sicher, dass du bei deinem Code-Beispiel nichts vergessen hast?
-
Setze einen Data Breakpoint auf die Adresse des Zeigers, der sich ändert.
-
@_matze:
Im Konstruktor von A sieht ja noch alles wunderbar aus und m_piData ist dort auch mit NULL initialisiert. Beim Verlassen des Basisklassenkonstruktors ändert sich aber aus irgendeinem mir unbekannten Grund die Speicheradresse des Pointers m_piData. Und dort wo dieser Zeiger dann auf einmal liegt ist der Speicher (also die Speicheradresse auf die der Pointer verweist) nicht auf NULL initialisiert.@Bashar:
Hab mir aber gerade mal angeschaut wie man "Data breakpoints" setzt. Ich werde das mal mit dem this pointer vom Objekt WhatEver machen. Der "erste" Speicherbereich des m_piData Zeigers bleibt nämlich auf 00 00 00 00 initialisiert und ändert sich nicht.
-
GrosseVerzweifelung schrieb:
@_matze:
Im Konstruktor von A sieht ja noch alles wunderbar aus und m_piData ist dort auch mit NULL initialisiert. Beim Verlassen des Basisklassenkonstruktors ändert sich aber aus irgendeinem mir unbekannten Grund die Speicheradresse des Pointers m_piData. Und dort wo dieser Zeiger dann auf einmal liegt ist der Speicher (also die Speicheradresse auf die der Pointer verweist) nicht auf NULL initialisiert.Ich meine, dass bei mir auch nach der Konstruktion alles ok ist. Hast du dein gebasteltes Beispiel selbst mal ausprobiert?
-
Nein, dieses Testprogramm hatte ich bisher noch nicht ausprobiert. Das sollte ja auch mehr oder weniger nur das Konstrukt hier bei mir erklären. Das ganze lief vor ca. 2 Wochen noch und eben als ich an der Stelle noch einmal etwas testen wollte, kam es zu diesem Fehler. Seit dieser Zeit (2 Wochen) hatte ich auch nichts aus dem CVS ausgecheckt, so dass es wenn eine Änderung von mir hätte sein können, die diesen Fehler verursacht hat. Doch an sich habe ich dort nichts gemacht (typischer DAU-Satz ... ich weiss).
Aber das ganze hat sich wahrscheinlich eh erstmal erledigt.Bei mir ist nämlich Zauberei am Werke. Der Fehler ging, wie er kam. Ich weiss jetzt echt nicht woran das gelegen hat, aber der Fehler ist weg. Ich habe jetzt halt eine ganze Zeit im Release-Modus (mit Debug-Informationen) gearbeitet und gerade als ich den Punkt mit dem Data-Breakpoint einmal testen wollte, läuft es auf einmal wieder
Zuvor hatte ich aber auch bereits einen kompletten Rebuild im Debug-Modus gemacht, so dass es auch nicht am Neuerstellen der DLL's liegen kann.Ich fürchte, dass ich jetzt wohl dumm sterben muss und ich nie erfahren werde was da passiert ist.
Aber trotzdem viel Dank für Eure Mühen.
-
Der Fehler ist sicher nicht durch Zauberei weg. Er ist nur gemein und versteckt sich. Du solltest dem weiter nachgehen, sonst zeigt er sich irgendwann später wieder (im schlimmsten Falle, wenn du keinen Einfluss mehr hast und das Programm beim User läuft).
-
ich vermute mal, dass an anderer stelle im code irgendwo über speichergrenzen hinaus geschrieben wird und das sich dadurch der zeiger von NULL auf irgwendeinen wert ändert.