Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zugriffsverletzung nach Objektzerstörung innerhalb Thread (https://www.delphipraxis.net/81646-zugriffsverletzung-nach-objektzerstoerung-innerhalb-thread.html)

Pfoto 30. Nov 2006 17:10


Zugriffsverletzung nach Objektzerstörung innerhalb Thread
 
Ok, nachdem ich schon seit längerem an einem wiederkehrenden Fehler hänge, folgende Situation:

1) Ich übergebe einem Thread eine Objektliste
2) Thread holt sich erstes Objekt aus der Liste und tut etwas damit
3) Objekt wird mittels .free anschließend gelöscht
4) Der Thread wird beendet und die Anwendung läuft ohne Probleme weiter
5) Beim Schließen der Anwendung kommt der Crash (Zugriffsverletzung bei Adresse 00000000)

Arbeite ich dieselbe Objektliste ohne Thread durch, entsteht kein Fehler.
Es entseht ebenfalls keine Fehlermeldung, wenn ich dieses Objekt nicht zerstöre - aber es hängt ja noch im Speicher...

Die Objektliste habe ich so erstellt, dass sie nicht selbst die Objekte freigeben soll,
wenn die Liste geleert wird.


Gibt es grundsätzlich Beschränkungen, wenn man ein Objekt innerhalb eines Threads löschen will?
Wahrscheinlich doch nur, hinsichtlich Mehrfachzugriff, oder?

Zugriffsverletzung bei Adresse 00000000 heißt doch, dass ein Objektzeiger bereits auf NIL steht und ich trotzdem darauf zugreifen möchte, oder?


Vielleicht habt ihr ja noch Gedanken dazu, die ihr loswerden wollt,


Folgende Anmerkunge möchte ich noch machen:

Es sind Objekte, die von TObject abgeleitet sind.

Die Objekte, die ich freigeben will, sind wiederum abgeleitet.
Freigegeben wird mit Hilfe des Ursprungsobjektes, also so:
Delphi-Quellcode:
Type
  TElternObjekt = class
  end;
 
  TKindObjekt = class(TElternObjekt)
  end;

 
KindObjekt:= TKindObjekt.Create;

{ ... tue was damit ... }

{ Jetzt freigeben über TElternobjekt }

TElternObjekt(KindObjekt).free;
Aber wenn das nicht gültig wäre, wieso funktioniert es dann ohne Thread-Umgebung?

Dank und Gruß
Pfoto

Bernhard Geyer 30. Nov 2006 17:17

Re: Zugriffsverletzung nach Objektzerstörung innerhalb Threa
 
Kurze Frage: Welche Art von Objekten sind das?
Von TComponent abgeleitete welche als Owner ein Formular oder ein anderes Control haben bzw. TControl und Parent gesetzt?

DGL-luke 30. Nov 2006 19:42

Re: Zugriffsverletzung nach Objektzerstörung innerhalb Threa
 
Könnte es sein, dass irgendetwas versucht, das Objekt obwohl schon gelöscht noch einmal freizugeben? Dann solltest du es aus der Liste löschen, nachdem du es freigegeben hast.

Christian Seehase 30. Nov 2006 22:22

Re: Zugriffsverletzung nach Objektzerstörung innerhalb Threa
 
Moin Pfoto,

meine erste Frage:

Delphi-Quellcode:
TElternObjekt(KindObjekt).free;
Was bezweckst Du denn damit?

Pfoto 1. Dez 2006 08:04

Re: Zugriffsverletzung nach Objektzerstörung innerhalb Threa
 
Der Zweck:
Natürlich ist die Sache etwas komplizierter und zieht sich über mehrere Objekte und Units, so dass ich nur exemplarisch etwas Code dargestellt habe.

Grundsätzlich versuche ich das Command-Pattern in Delphi nachzubauen, was ja nicht so schwer ist. Probleme gibt es bei Zerstörung von zuvor weitergegebenen Objekten (bzw. deren Pointern)

Das Pattern besitzt Kenntnisse nur von der Eltern-Klasse, so dass es für die verschiedenen Projekte nicht verändert werden muss.
Ich leite von der Eltern-Klasse im Projekt kann konkrete Kind-Klassen ab und übergebe diese dem Command.
Alles funktioniert bis hier hin. Wenn ich nach der Abarbeitung des Commands im Thread das übergebene Objekt zerstören will, tritt eine Schutzverletzung auf. Eine Zerstörung funktioniert aber wie gesagt grundsätzlich mit der oben erwähnten Vorgehensweise -- nur nicht bei Abarbeitung im Thread.

Gruß
Pfoto

Bernhard Geyer 1. Dez 2006 08:35

Re: Zugriffsverletzung nach Objektzerstörung innerhalb Threa
 
1, TElternObjekt(KindObjekt).free; ist völlig unnötig. KindObjekt.Free reicht vollkommen aus.

2, Wenn du das Programm in der IDE beenden läßt, springt die IDE dann nicht an die entsprechende Code-Zeile? Falls nicht, hast du schon mal mit Debug-DCU's gearbeitet? Ansonsten kannst Du mal probieren mit FastMM4 oder MemCheck den Fehler auf den Grund zu gehen.

Gausi 1. Dez 2006 08:48

Re: Zugriffsverletzung nach Objektzerstörung innerhalb Threa
 
TList, und somit auch TObjectlist, sind nicht threadsafe. Wenn man solche Listen in Threads verwenden möchte, muss sichergestellt sein, dass wirklich immer nur ein Thread auf diese Liste zugreift! D.h. wenn der Nebenthread mit der Liste arbeitet, darf der Hauptthread nicht auf diese Liste zugreifen. ganz besonders gefährlich sind dabei natürlich Schreibzugriffe (Stichwort: Umkopieren des Zeigerarrays).
Eine Möglichkeit sind TThreadlists. Oder man macht das selbst und arbeitet mit Criticalsections.

Zu dem zerstörten Objekt: Wird das auch aus der Liste entfernt? Hilft es, wenn du nicht nur Free aufrufst, sondern FreeAndNil?


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:42 Uhr.

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