Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Kein Zugriff auf Private Variablen (https://www.delphipraxis.net/194174-kein-zugriff-auf-private-variablen.html)

Purri 25. Okt 2017 10:35

Kein Zugriff auf Private Variablen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

ich bekomme in meiner Testanwendung eine Zugriffsverletzung, die mir nicht ganz klar ist. Hoffentlich kann mir einer von euch sagen, was ich falsch mache...:oops:

Ich möchte mir einen Thread-Manager bauen, bei dem sich alle meine Threads registrieren, damit ich diese zentral verwalten kann. Natürlich möchte ich dann auch über den Manager die Threads stoppen und freigeben können. Ich gehe also im Destroy des Threadmanagers meine Liste durch und rufe für laufende Threads ein Free auf, was im Destroy des Threads schlieslich wieder die "RemoveThread"-Routine des Managers aufruft. Und hier kommt das Problem: Dort kann ich plötzlich nicht mehr auf die private Variable des Threadmanagers zugreifen und erhalte eine Zugriffsverletzung :?.

Im Anhang findet Ihr die Testanwendung: 1. Threadmanager starten, 2. Thread starten, 3. Threadmanager stoppen -> Fehler

Kann mir einer von euch sagen, was ich übersehe/falsch mache?

Der schöne Günther 25. Okt 2017 10:40

AW: Kein Zugriff auf Private Variablen
 
Setze mal einen Haltepunkt bei

Delphi-Quellcode:
procedure TTestThread.RemoveThread;
begin
  gThreadManager.RemoveThread(Self)
end;
und denk mal nach ;-)

Purri 25. Okt 2017 10:54

AW: Kein Zugriff auf Private Variablen
 
Hallo Günther,

ich sehe da leider kein Problem :oops: (Außer vll. das fehlende Semikolon, aber das macht keinen Unterschied :wink: ).

Wenn ich den Thread alleine beende, also per Klick auf den Thread-Stop-Button, funktioniert übrigens alles, auch das RemoveThread.

bra 25. Okt 2017 11:34

AW: Kein Zugriff auf Private Variablen
 
Du übergibst in dem Thread Self an den Threadmanager und versuchst den zu Löschen (Free). Das kann nur schief gehen :wink:

Der schöne Günther 25. Okt 2017 11:35

AW: Kein Zugriff auf Private Variablen
 
Dein
Delphi-Quellcode:
gThreadManager
ist zu dem Zeitpunkt schon
Delphi-Quellcode:
nil
da du vorher schon
Delphi-Quellcode:
FreeAndNil(gThreadManager)
gemacht hast.

Purri 25. Okt 2017 11:45

AW: Kein Zugriff auf Private Variablen
 
Ok, ich verstehe was ihr meint, aber nicht warum das so ist.

Ich habe jetzt das FreeAndNil durch
Delphi-Quellcode:
  gThreadManager.Free;
  gThreadManager := nil;
ersetzt. nun klappt es.

Danke.:thumb:

Zum Verständnis:
Ich befinde mich doch eigentlich immer noch im Destructor vom ThreadManager, also dürfte er doch nicht schon weg sein? Ein Blick in den FreeAndNil-Code zeigt: Zuerst wird := nil gesetzt und erst danach .Free aufgerufen.... Ich fühle mich von Delphi verar****:roll: So isses doch wohl eher NilAndFree :lol:

Gibt es einen guten Grund, warum diese Reihenfolge ausgeführt wird?

Blup 25. Okt 2017 12:04

AW: Kein Zugriff auf Private Variablen
 
Deine Instanz des ThreadManager existiert zu diesem Zeitpunkt noch. Nur der globale Zeiger "gThreadManager" auf diese Intstanz zeigt bereits auf nil. Zugriffe über nil-Pointer löst Zugriffsverletzung aus.

Purri 25. Okt 2017 12:08

AW: Kein Zugriff auf Private Variablen
 
Danke Blub,
das habe ich verstanden und schon geändert. Ich frage mich nur noch, warum FreeAndNil zuerst den Zeiger löscht und dann die Instanz, anstatt es andersrum zu machen, wie ja auch der Name es vermuten lässt.

bra 25. Okt 2017 12:35

AW: Kein Zugriff auf Private Variablen
 
Zu dem Sinn und Unsinn von FreeAndNil gibt es dutzende Diskussionen. Einige sagen, man sollte es oft verwenden, andere nie. Und ich glaube beide haben Recht :lol:

Zacherl 25. Okt 2017 17:26

AW: Kein Zugriff auf Private Variablen
 
Zitat:

Zitat von bra (Beitrag 1384103)
Zu dem Sinn und Unsinn von FreeAndNil gibt es dutzende Diskussionen. Einige sagen, man sollte es oft verwenden, andere nie. Und ich glaube beide haben Recht :lol:

Kommt definitiv immer auf den konkreten Fall an.
  • Geht es um eine Klasseninstanz, die ausschließlich lokal in einer Funktion verwendet (und erstellt) wird, kann man sich das
    Delphi-Quellcode:
    FreeAndNil
    fast immer sparen und nur
    Delphi-Quellcode:
    Free
    aufrufen, da die Variable nach dem Verlassen der Funktion eh aus dem Scope läuft/vom Stack entfernt wird.
  • Bei globalen Instanzen kommt es drauf an, ob die Instanz dynamisch (bei bestimmten Aktionen) erstellt und freigegeben wird (und das Vorhandensein über einen
    Delphi-Quellcode:
    <> nil
    Check umgesetzt wird).

Delphi-Quellcode:
FreeAndNil
"nur so" zu verwenden, weil man das Gefühl hat, dann ordentlich aufgeräumt zu haben, ist nur unnötiger Overhead.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:45 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz