Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Pointer Problem


Zuckerwatte - Di 02.09.03 13:43
Titel: Pointer Problem
Hallo,

ich habe 2 Listen mit Pointer auf Objekte.
Wenn eine Liste gelöscht wird, dann werden auch alle Objekte zu diesen Pointern gelöscht, und die Pointer selbst auf NIL.

In der 2. Liste ist ein Pointer auf ein Objekt, welches schon über einen Pointer aus der 1. Liste referenziert wurde.

Wenn beim löschen der 2. Liste nun dieser Pointer mit dem Objekt gelöscht werden soll, dann gibt es eine Zugriffschutzverletzung, weil das Objekt nicht meht vorhanden ist.

Wie kann ich Prüfen, ob zu einem Pointer das entsprechende Objekt noch existiert?
Oder wie kann ich beim erstmaligen löschen des Objektes alle Referenzierenden Zeiger ermitteln und die auf NIL setzen?


CenBells - Di 02.09.03 13:49

hallo,

du kannst probieren, ob in deinem Fall die funktion assigned(Pointer) funktioniert. Die würde dir beim löschen der zweiten liste helfen.

Gruß
Ken


Zuckerwatte - Di 02.09.03 14:03

Hallo Ken,

da der Pointer in der 2. Liste nie auf NIL gesetzt wurde, schlägt
die Function assigned(Pointer) nie an.

Gruß Zuckerwatte


barfuesser - Di 02.09.03 15:47

@Zuckerwatte: Wenn Du das referenzierte Object (MyObject) aus der einen Liste löschst, dann kannst Du doch mittels

Delphi-Quelltext
1:
list2[list2.IndexOf(MyObject)] := nil                    

die Referenz aus der 2. Liste auf nil setzen oder mit

Delphi-Quelltext
1:
list2.Delete(list2.IndexOf(MyObject))                    

gleich löschen.

barfuesser[/delphi]


CenBells - Di 02.09.03 17:11

Zuckerwatte hat folgendes geschrieben:
Hallo Ken,

da der Pointer in der 2. Liste nie auf NIL gesetzt wurde, schlägt
die Function assigned(Pointer) nie an.

Gruß Zuckerwatte


du meinst, assigned liefert nie true? Dann ist der pointer nil...

Gruß
Ken


barfuesser - Di 02.09.03 17:24

@CenBells: Assigned überprüft nur ob der Zeiger gleich nil ist. Dies dürfte aber in der zweiten Liste nicht der Fall sein. Im Gegenteil, die Einträge in der zweiten Liste zeigen auf die Stellen im Speicher, an denen jetzt keine Objekte mehr existieren.

barfuesser


CenBells - Di 02.09.03 17:36

barfuesser hat folgendes geschrieben:
@CenBells: Assigned überprüft nur ob der Zeiger gleich nil ist. Dies dürfte aber in der zweiten Liste nicht der Fall sein. Im Gegenteil, die Einträge in der zweiten Liste zeigen auf die Stellen im Speicher, an denen jetzt keine Objekte mehr existieren.

barfuesser


ja, ich weiß, ich fand nur, dass sich die zuckerwatte etwas unverständlich ausgedrückt hat...

Gruß
Ken


Zuckerwatte - Mi 03.09.03 12:23

Hallo barfuesser,

das ist eine gute Idee.

Ich habe jetzt ein weiteres Problem. Ich habe beliebig viele Instanzen von meiner Listen-Klasse. D.h, ich muss zur Laufzeit auf die Instanzen zugreifen können. Da meine Listen-Klasse aber nur von TObject abgeleitet ist, habe ich keine möglichkeit wie bei TComponent über eine Schleife auf Klassengleichheit durchzuprüfen. Hast Du eine Idee wie ich an alle vorhandenen Instanzen meiner Listen-Klasse komme???

Gruß
Zuckerwatte


barfuesser - Mi 03.09.03 15:40

Ich verstehe nicht ganz, was Du willst. Also Du hast zwei Listen mit Zeigern auf Objekte. Und von diesen Listen hast Du mehrere Referenzen. Und nun möchtest Du zur Laufzeit alle Referenzen auf eine der Listen erhalten? Das ganze begreife ich nicht. Du legst doch die Referenzen selber an, warum mußt Du sie dann erst suchen?

barfuesser


Zuckerwatte - Mi 03.09.03 17:48

Ich habe nicht nur 2 Listen sondern x beliebige. In jeder dieser Listen kann evtl. ein Pointer vorhanden sein der auf den selben Adressbereich(Objekt) zeigt. Letztendlich werden alle Listen beim Programmende freigegeben. Beim Freigeben einer Liste gebe ich in der Destroy-Routiene alle zugehörigen Objekte frei und setze die Pointer auf Nil. An dieser Stelle würde ich gerne alle anderen existierenden Listen mit deiner Methode durchsuchen, und evtl gefundene Pointer auf NIL setzen. Nur kenne ich an dieser Stelle nicht alle erzeugten Listen. Da ich mir die Listen beim erstellen nicht in einer anderen globalen Liste merken möchte, dachte ich es gäbe vielleicht die Möglichkeit alle vorhandenen Klassen in einer Schleife zu durchlaufen und daran zu erkennen, das es sich um eine Listen handelt.

Ich hoffe es ist nun etwas klarer geworden.??

Gruß Zuckerwatte


barfuesser - Mi 03.09.03 17:55

Ja, es ist klarer geworden. Und es geht nicht! Aber beschreibe mal wofür Du das brauchst, vielleicht kann man das ja anders lösen.

barfuesser


Zuckerwatte - Mi 03.09.03 19:00

Ich möchte eine Rechtezuordnung erstellen. Hierzu möchte ich ein TreeView verwenden. Zu jedem Node möchte ich beliebig viele Rechte zuordnen können. Dazu gehe ich folgendermassen vor: Ich erstelle eine Klasse "TRecht" Dann erstelle ich noch eine Klasse "TRechteList" Somit kann ich beliebigviele Rechte in einer Liste mit Pointern verwalten. Den Pointer einer Liste ordne ich dann der Eigenschaft "node.data" zu.

Letztendlich möchte ich eine Liste haben, worüber alle Rechte verwaltet werden und einmalig erzeugt werden, und für jedes "TreeView.Node.data" eine weitere Liste, wo mehrere Rechte aus der Gesamtliste verwaltet werden(Nur Pointer in der Liste, Somit habe ich die Rechte nur einmal im Speicher).

Dieses ganze Konstrukt möchte ich dann gerne in ein Datenbank-Blobfeld speichern können und auch wieder auslesen können. Das wird bestimmt auch nicht so einfach, da man anscheinend für alle dynamischen Größen voher auch noch die entsprechende Größe abspeichern muss, bzw. die Anzahl. :-(

Gruß Zuckerwatte


barfuesser - Do 04.09.03 09:57

Hi,

wenn Du die zentrale Liste aller Rechte als erstes leerst, dann brauchst Du danach nur noch die einzelnen Rechtelisten freizugeben, da die Zeiger in ihnen dann schon ins Nirvana zeigen und die Objekte dahinter nicht mehr existieren. Wenn Du nur eine einem Node zugeordnete RechteListe löschen möchtest, dann darfst Du die referenzierten Objekte nicht freigeben, da sie dann Zeiger ins Nirvana in allen anderen Listen zurücklassen.

barfuesser