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


  • Mod

    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!


Log in to reply