Visual C++ 4.0 embedded; Objekte einer Methode auf Stack oder Heap -> Absturz oder OK?
-
Hallo zusammen,
ein schon lange in Betrieb befindliches Programm auf einem embedded WinCE Rechner
hat ein Problem:
Es wurde innerhalb eines Dialoges in einer "OnButton"-Methode von einer weiteren
Klasse ein Stack basiertes Objekt erstellt. Das sieht so aus:CAnlageImpfen cImpfen(cOrignalAdresse.GetBuffer(0),&strAnlagenAdressen,TELNET_TCPIP_SEND,NULL,NULL,NULL,m_pView->m_hWnd); cImpfen.SetPort(m_pAnlage->m_Anlage.sDsc.uiTelnetPort); if(cImpfen.DoModal()) { if(m_pAnlage->IsAktiv()) m_pAnlage->ResetConnect(); }
Man kann daraus erkennen, dass es über Telnet eine angeschlossene Anlage manipulieren soll.
Dieses Objekt ist selbst kein Dialog (wegen "DoModal"), es enthält aber ein modales Ausgabefenster.Aber der Effekt des Ganzen:
Dieses Code-Fragment vernichtet, alleine durch erzeugen des Objekts in der ersten Zeile,
die gesamte Methode, in der es drin steckt.
Im Debugger kann keine Variable in diesr Methode gelesen werden!
Und der Versuch, den Konstruktor auszuführen endet im Nirvana. Ohne dieses Code-Fragment läuft es korrekt.Ein annähernd gleiches Programm (weitgehend identischer Quellcode, durch Compilerdirektiven ans
jeweilige System angepasst) wird auf einem normalen PC ausgeführt.
Dort macht dieses Code-Fragment keine Schwierigkeiten.Ich bin nun einfach hergegangen und lege diese Objekt auf den Heap:
CAnlageImpfen *pImpfen = new CAnlageImpfen(cOrignalAdresse.GetBuffer(0),&strAnlagenAdressen,TELNET_TCPIP_SEND,NULL,NULL,NULL,m_pView->m_hWnd); pImpfen->SetPort(m_pAnlage->m_Anlage.sDsc.uiTelnetPort); if(pImpfen->DoModal()) { if(m_pAnlage->IsAktiv()) m_pAnlage->ResetConnect(); } delete pImpfen;
Nun funktioniert es!
Ich muss noch dazu sagen, dass die ganze Anwendung auf mich keinen sehr vertrauenswürdigen Eindruck macht.
Ich habe nur kurz reingesehen und feststellen müssen, dass bei keiner Basisklasse virtuelle Destruktoren
verwendet wurden, manchmal fehlen sie ganz, und sie werden dann auch, wie hier, im Stack erstellt.
Also ich habs nicht selbst geschrieben. Aber es funktioniert sonst wohl alles.Was meint ihr dazu?
-
Leider scheint niemand eine Meinung dazu zu haben.
Mich hätte interessiert, wie ich diesen Zustand beurteilen kann/soll.
Vielleicht hatte schon mal jemand etwas Ähnliches.
Ich habe an anderen Stellen schon seltsame Fehler beseitigt, indem
ich andere Fehler (Deklarations-Nachlässigkeiten, die den Compiler nicht störten)
beseitigt hatte.Aber in diesem Fall bin ich erst mal zufrieden, dass ich mit meinem intuitiven
Ausprobieren Erfolg hatte. Ich kann mich ja beim nächsten Umbau wieder
mit dem Ausmerzen von Nachlässigkeiten befassen.Danke fürs Lesen
-
Das geht auch in der Debug Version?
Objekte auf dem Stack werden evtl. schneller überschrieben als die auf dem Heap.
Alleine das kann bei einem multithreaded Programm zu solchen Problemen führen.Also gehe ich mal davon aus, dass der Heap zerstört wird und Du es nicht merkst.
Beim Stack krachst es aber, weil der Stack eben überschrieben wird.Ich würde bei diesem Fehler sehr hellhörig werden.
-
Vielen Dank Martin für Deine Antwort.
Ja, das geht in der Debug-Version.
Hier konnte ich das Verhalten erst feststellen.Es ist sogar so, dass das ganz oben angegebene Stück Quellcode schon durch
die Anwesenheit der Deklaration von "CAnlageImpfen cImpfen(..." die Methode
beeinträchtigt, in der sie drin steckt. Man kann sich aus dieser Methode keine
Variablenwerte im Debugger mehr anzeigen lassen. Die werden alle als nicht
zugreifbar angsehen. Abstürzen tut das ganze dann erst beim Versuch, das
Objekt anzulegen. Und sobald ich einen Pointer aus "cImpfen" mache,
tauchen diese Probleme nicht mehr auf.Mir ist in der Klasse "CAnlageImpfen" allerdings nichts seltsames aufgefallen.
Sie funktioniert ja nun auch, als Pointer.Bisher hatte ich noch keine Zeit, das ganze Programm durchzusehen und
zu überarbeiten. Bis auf diesen Fehler scheint es zu laufen, und das schon
recht lange.Auf jeden Fall bin ich hellhörig geworden!
-
Eventuell Stacksize vs. sizeof(CAnalageImpfen)?
-
Das hatte ich mir auch schon überlegt, aber ein anderer Kollege meinte,
das könne es nicht sein.
Ich würde in diesem Fall eigentlich eine übliche "Stack overflow" Meldung erwarten.Ich werde wohl in dieser Richtung nochmals nachforschen (Hab nur gerade eine neue Aufgabe).
Aber wenn das wirklich er Grund gewesen wäre, dann hätte ich ja intuitiv schon die richtige Lösung gefunden. Aber noch eine Kontrolle mehr ist in diesem Fall sicher kein Fehler.
Danke nochmals!