Thread aus Tutorial



  • Hallo Leute,
    ich habe mir das Threads Turorial angesehen und durchgearbietet.
    (http://bcb-tutorial.c-plusplus.net/Thread/artikel5.html)
    Das hat sogar alles funktioniert wie es soll. Dann habe ich mein Programm weiter ausgebaut. Danach aber konnte ich nicht mehr auf die Elemente auf Form1 zugrifen, ich bekomme immer eine Zugriffsverletzung. Daraufhin habe ich meinen Code wieder soweit reduziert wie im Tutorial:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    
           new TReadComThread(false);
    }
    

    Im Header

    class TReadComThread : public TThread
    {
    private:
            //AnsiString Command;
            //TQueueThread *Q;
            //TUart *U;
            int FCount;
    
    protected:
            void __fastcall Execute();
            void __fastcall GuiElements();
    public:
            __fastcall TReadComThread(bool CreateSuspended);
    
    };
    
    __fastcall TReadComThread::TReadComThread(bool CreateSuspended)
        : TThread(CreateSuspended)
    {
        FreeOnTerminate = true;
    }
    
    void __fastcall TReadComThread::GuiElements()
    {
            //Da wir uns nicht im Gültigkeitsbereich von Form1 befinden, müssen wir qualifizieren mit Form1.
            Form1->Caption = IntToStr(FCount); [b]<- da tritt der fehler auf[/b]
    }
    
    void __fastcall TReadComThread::Execute()
    {
            FCount = 0;
            while (FCount < 1000)
            {
                    Synchronize(&GuiElements);
                    FCount ++;
    
            }
    }
    
    //---------------------------------------------------------------------------
    

    Ich habe sonst nix am laufen, keine OnCreate Routine oder sonstwas.
    Hat jemand eine Ahnung, waum ich so eine Zugriffsverletzung bekomme?
    Viele Grüße SImon

    P.S.: Sorry, dass ich den Artikel hier gepushed habe, das war ein totales Versehen.



  • Ist denn evtl. Form1 da nicht mehr gültig? Bist du mal mit dem Debugger durchgegangen (Breakpoint setzen)?



  • Hallo,
    also wenn Form1 dort nicht mehr gültig ist, müsste mir dann nicht der Compiler einen Fehler melden?
    Grüße Simon



  • Hallo

    Der Compiler würde einen Fehler bringen, wenn der Zeiger Form1 an der besagten Stelle nicht bekannt ist. Das ist ja nicht der Fall.
    Aber wenn zur Laufzeit der Zeiger auf einen Speicherbereich zeigt, in dem keine gültige Instanz liegt, dann kommt zur Laufzeit eine Zugriffsverletzung. Das meint Braunstein. Das könnte zum Beispiel passieren, wenn das Form schon geschlossen ist, aber der Thread immer noch läuft.

    bis bald
    akari



  • Aktiviere mal CodeGuard in den Projektoptionen; dann wirst du über falsche Speicherzugriffe benachrichtigt.



  • Hallo,
    danke zunächst schonmal für die Denkanstöße, ich bin nur leider im MOment nicht dazu gekommen das Problem anzugehen.
    Ich hab da aber noch eine Frage: so wie's im Tutorial steht hat es ja schon funktioniert. Ich habe dann allerdings das "Unit2.h" und "Unit1.cpp" aus dem Projekt entfernt und alles in eine eigene "hpp" Datei rein. Dabei habe ich ausser "#include <classes.hpp>" und außer den Klassendeklarationen etc nicht weiter übernommen. Könnte es auch damit was zu tun haben?
    Was das Debuggen etc angeht werde ich das mal durchführen sobald ich dazu zeit finde.
    Viele Grüße Simon



  • Hi,
    also ich habe über den Debugger mir jetzt den Haltepunkt gesetzt und mir dann Form1 ausgeben lassen. Woran kann ich jetzt erkennen, ob da der Wurm drin ist? Meinem Bauchgefühl nach ist da alles OK, weil eine Adresse hinterlegt ist (also nicht NULL) und weil sogar die Elemente auf Form1 im Objektinspektor angezeigt werden.
    Hat sonst jemand eine Idee, was da das Problem sein könnte? Sollte es einen Unterschied machen wo die Threadobjekte untergebracht sind? Eigentlich doch nicht oder?
    Grüße Simon



  • Edit: Unfug.



  • Update:
    ich habe zum Spaß einfach nochmal ein Tutorial-Projekt erzeugt. Hat funktioniert.
    Nachdem, ich den Inhalt der unit1.h in die unit1.cpp kopiert habe und unit1.h absolut auskommentiert habe, bekomme ich den Fehler wieder. Es liegt also doch daran, wo die Sachen untergebracht sind. Kann mir das jemand erklären? Ebenfalls funktioniert es nicht, alles ausd er unit1.cpp in die unit1.h zu kopieren und unit1.cpp auszukommentieren.
    ?
    Non comprendre.

    Simon



  • Irgendwie verstehe ich dein Problem nicht so ganz.

    In deinem Thread musst Du doch, vor allem für ein solch Simples Tutorial, nur den Header deiner Form1 einbinden. (Unit1.h)?

    Form1->Caption = IntToStr(FCount);
    

    Woher sollte er sonst Form1 kennen?

    Execute() wenn Du dir einen Quelltext haltepunkt im Debugger setzt der nie erreicht wird, kann man zu 90% davon ausgehen das dieser Punkt auch nie erreicht wird 😉

    Wenn ich nicht gerade absolut auf dem Schlauch stehe wird Execute() erst ausgeführt, sobald Du nach der der Thread-Objekt deklaration auch noch Resume() aufrufst.

    myThread th = new myThread(NULL);
    myThread->Resume();
    

    Hoffe das ich nicht gerade am Thema vorbei schreibe aber der `Fred` hier ist etwas verwirrend!


Anmelden zum Antworten