TList Remove - Objekte freigeben
Übersicht

![]() |
TrustBetreff: TList Remove - Objekte freigeben |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
wird der Speicher tatsächlich beim unten stehenden Beispielcode freigegeben? (Nach dem Code die Erklärung) BlitzMax: [AUSKLAPPEN] SuperStrict Ich habe eine Liste für Objekte um diese alle in einem Rutsch Updaten und Zeichnen zu können. Zusätzlich habe ich das Handle des Objekts in einer Variable um geziehlt mit einem Objekt hantieren zu können. Um es auf mein vorhaben zu beziehen: Ich arbeite zur Zeit an einer IsoMap-Engine, und dort soll der Benutzer dieser Engine einfach Objekte erstellen können (wie zB. Spieler oder Gegner usw.) und diese auch einfach wieder löschen können. Wie und wann die Objekte gezeichnet werden, damit diese den Richtlienen der Isoperpektive entsprechen (Spieler hinter der Mauer oder davor, oder Spieler hinter dem Gegner oder davor usw. usf.) regelt die Engine. Dazu hat diese eine Liste aller Objekte welche für den Benutzer der Engine allerdings nicht einsehbar ist, damit er diese nicht verändern kann, da es sonst zu Fehldarstellungen auf der Map kommen kann. Klappt auch alles Wunderbar, läuft sehr schnell und alles, nur eben das o.g. bereitet mir Kopfzerbrechen. Denn die Objekte existieren noch nach "myObj.Destroy()" - also nach dem Entfernen aus der Liste. Bei Userspeziefischen Typen werden doch nur die Referenzen in BMax zurückgegeben? Habe es auch schon mit der Adresse versucht, aber Pointer in BMax kann man komplett vergessen für sowas. BlitzMax: [AUSKLAPPEN] Function Create:TMyType(foo:Int) Funktioniert nicht. (Illegal Pointer Type) Da man keine Pointer von Userspeziefischen Typen erstellen kann. Und so: BlitzMax: [AUSKLAPPEN] Local myObj:TMyType = TMyType.Create(1) Weiss ich nicht wie ich es zurück casten kann... Ich glaub BMax ist nicht meine Sprache ![]() |
||
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen. |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Um ein Objekt wieder zu zerstören, genügt es nicht, es von der TList zu entfernen. Es "lebt" ja noch zusätzliche als myObj. Also wirst du das auch zerstören müssen.
BlitzMax: [AUSKLAPPEN] Type TMyType dies wäre ein weiterer Weg: BlitzMax: [AUSKLAPPEN] Type TMyType |
||
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe |
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du könntest die Delete-Methode überladen, um dir die Aktion des GC anzeigen zu lassen:
BlitzMax: [AUSKLAPPEN] Type TMyType Die wird aber nie sofort ausgelöst, wenn alle links zum Objekt verloren sind, sondern erst wenn der GC eine Runde sauber macht. Eine Lokale Variable in der Hauptschleife musst du selbst Null setzen, da sie ja die ganze Laufzeit über gilt. In Funktionen/Schleifen wird die Variable wieder frei gegeben, darum musst du dich nicht um o:TMyType kümmern. Kein Grund mit Pointern zu hantieren ![]() |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Trust |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo
@MidiMaster Zitat: Es "lebt" ja noch zusätzliche als myObj. Also wirst du das auch zerstören müssen.
Das hat mich ja grade verwirrt. Es heisst, dass in BMax userspeziefische Types bei der Rückgabe nicht dupliziert werden, sondern nur die Referenz zurückgegeben wird. Deswegen dachte ich, wenn ich das Objekt aus der Liste lösche, ist myObj null, da eine Referenz auf ein Objekt verweisst, dass nicht exsistiert. Eine Referenz ist ja eigentlich ähnlich wie ein Pointer - mit der Ausnahme, dass die Addresse sich durch den GC ständig verändert, diese aber zurückverfolgt wird. (Tracking Reference) Aber scheinbar löscht die Anweisung "List.Remove()" nicht das Objekt, sondern entfernt nur den Eintrag in der Liste. BlitzMax: [AUSKLAPPEN] Method Destroy:TMyType()Funktioniert leider nicht, hatte ich auch schon versucht. Zitat: Function Destroy_II:TMyType(Me:TMyType)
Hab ich auch schon versucht, allerdings ein wenig vereinfacht:
MyList.Remove Me Return Null End Function BlitzMax: [AUSKLAPPEN] Nicht grade elegant. Aber ist glaube ich die einzige Möglichkeit. @Xeres Es wäre eine schöne Lösung gewesen wenn der Benutzer nur die Adressen der Objekte bekommt, und beim zerstören der Objekte automatisch der Pointer Null ist. So würden keine grossen Massen im Speicher herumgeschoben werden und alles. Und wie ist das genau, erstellt BMax eine Kopie bei der Rückgabe bei eigenen Types? |
||
- Zuletzt bearbeitet von Trust am Mo, Mai 28, 2012 14:50, insgesamt einmal bearbeitet
![]() |
ZEVS |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich sehe nicht ganz ein, was dein Problem ist. Gut, in diesem Falle musst du zudem darauf achten, dass du noch eine Referenz in einer extra Variable rumzustehen hast, aber dies ist doch nur zu Testzwecken. Später hast du doch gewiss keine weiteren Referenzen auf die Objekte als die Liste - schließlich kannst das kompillierte Programm nicht einfach beliebig Variablen erstellen.
Zitat: Und wie ist das genau, erstellt BMax eine Kopie bei der Rückgabe bei eigenen Types?
Nein Zitat: Aber scheinbar löscht die Anweisung "List.Remove()" nicht das Objekt, sondern entfernt nur den Eintrag in der Liste.
Normalerweise - und das ist gut so - löscht nur GC Objekte. Wenn es dir Freude bereitet, kannst du BlitzMax: [AUSKLAPPEN] Release HandleFromObject(myObj) ausführen und zusehen, wie dir dein Programm beim Zugriff auf myObj abschmiert. Zitat: Es wäre eine schöne Lösung gewesen wenn der Benutzer nur die Adressen der Objekte bekommt, und beim zerstören der Objekte automatisch der Pointer Null ist.
Welche Benutzer meinst du? ZEVS |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Trust, BMax ist GC-kontrolliert. Mach Dir nicht zuviele Gedanken über im Speicher herumwuselnde Objekte.
Setz einfach alle Variablen die auf ein Objekt verweisen auf Null und der GC wird es irgendwann, wenn Speicher benötigt wird bzw. sich genug Müll gesammelt hat, entsorgen. Funktioniert einwandfrei, glaub es mir. Also: Du willst dein Objekt löschen? Entferne es einfach aus der Liste. Solange nicht jedes dieser Objekte in der Liste noch eine Entsprechung in einer anderen Variablen hat, werden sie bald Geschichte sein. Und das eine Objekt aus der Initialisierung in der lokalen Var aus dem Programmkopf wird deinen Speicher auch nicht überfüllen. Anders gesagt: Optimiere nicht wo es nichts zu optimieren gibt. Keep it simple, stupid! (Eine gute Verfahrensregel). |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Trust |
![]() Antworten mit Zitat ![]() |
---|---|---|
@ZEVS
Die IsoMap-Engine soll später als Modul vorliegen und wird dann die Grundlage meiner Action RPG-Engine welche später auch als Modul vorliegen soll und als Grundlage für den Action RPG-Maker/Editor dienen soll. Benutzer bin ich und die, welche die Engine später benutzen wollen. Möchte halt soviel kompfort bei der benutzung der Engine erreichen wie es nur geht. Dazu wollte ich unter anderem erreichen, dass der Benutzer sich nicht selber um das aufräumen und "Nullen" eigener Variablen kümmern muss, sondern die Engine selber schaut ob eine Referenz auf eine erstellte Variable besteht ,wenn nicht - nicht drauf zugreifen und aufräumen - wenn ja, dann gewünschte sachen mit anstellen. Damit auch durch unachtsames/schlampiges Progriemieren des Benutzers keine/weniger Bugs oder gar abstürze vorkommen. @BladeRunner Oftmals sind die einfachen Dinge dass, was einem das Leben schwer macht. ![]() Ist ein Problem von mir alles Ergründen zu wollen, bzw. wissen zu wollen was im Hintergrund abgeht. Hatte es schon damals gehasst mit Visual C++ und .Net programmieren zu müssen. Wahrscheinlich war auch das der Grund warum ich anfing ASM zu lernen. (Absolute Kontrolle über das was passiert) |
||
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen. |
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das Objekt wird mit New erstellt (ausschließlich) und steckt irgendwo im Speicher. Jede TMyType-Variable referenziert dieses Objekt. Sobald keine Variable mehr auf ein Objekt zeigt, wird der GC aktiv.
Das Einzige, was du bei deinem allerersten Code vergessen hast, ist die Lokale myObj-Variable, die du nicht null setzt. Wenn du das tust, fliegt dir der Code um die Ohren, weil du auf myObj._foo zuzugreifen versuchst. Wie gesagt: Um Lokale Variablen musst du dich gar nicht kümmern, ausgenommen den Spezialfall mit der Hauptschleife. Wenn du vergisst, Objekte aus Listen oder Arrays zu löschen, wird das Problem ganz offensichtlich sein... |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zitat: Dazu wollte ich unter anderem erreichen, dass der Benutzer sich nicht selber um das aufräumen und "Nullen" eigener Variablen kümmern muss, sondern die Engine selber schaut ob eine Referenz auf eine erstellte Variable besteht ,wenn nicht - nicht drauf zugreifen und aufräumen - wenn ja, dann gewünschte sachen mit anstellen. Damit auch durch unachtsames/schlampiges Progriemieren des Benutzers keine/weniger Bugs oder gar abstürze vorkommen.
Und genau das hast Du erreicht wenn Du dein Objekt aus der Liste löschst, solange Du keine anderen Verweise drauf hast. Du denkst zu komplex. BMax ist managed, es erledigt das für dich. Es ist nett (und wichtig!) verstehen zu wollen wie die Dinge laufen, aber das hat ja mit deinem Problem erst mal nix zu tun, denn genaugenommen gibt es kein Problem. |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Trust |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zitat: Und genau das hast Du erreicht wenn Du dein Objekt aus der Liste löschst, solange Du keine anderen Verweise drauf hast
Und da steige ich nicht ganz durch. Angenommen die IsoMap-Engine ist fertig und liegt als Modul vor. Dann importiere ich dieses in mein neues Projekt. Jetzt erstelle ich mir eine eigene Objekt-Klasse welche von der Objektklasse der Engine abgeleitet wird, welche unter anderem viele nützliche Methoden zur verfügung stellt und sich um das Management der Objekte kümmert. Nun erstelle ich ein neues Objekt meiner Klasse. Engineintern wird das Objekt einer Liste hinzugefügt welche nur der Engine bekannt ist. Die Engine ruft dann unter anderem die Drawmethode der eigenen Engineobjektklasse auf usw. . Damit die Engine bescheidweiss, welche Objekte existieren und wie und wann sie eingezeichnet werden müssen, hat sie die eigene Liste dafür. Wenn ich jetzt über mein Objekt die Methode Destroy aufrufe, löscht die Engine das Objekt aus der eigenen Liste und somit existiert das Objekt nicht mehr für die Engine. Jetzt hab ich als Benutzer das Problem das ich immernoch das Objekt habe und dessen Methoden aufrufen kann usw. . Ich wollte aber das aus der Engine heraus auch mein Objekt freigegeben wird usw. . Damit nicht irgendwann ein Haufen Objekte existieren die die Engine eh nicht mehr benutzen kann da sie von denen nichts weiß. Wie soll ich das am besten lösen? Hier einfach mal der TestCode den ich zum Testen der Engine benutze BlitzMax: [AUSKLAPPEN]
|
||
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen. |
- Zuletzt bearbeitet von Trust am Mo, Mai 28, 2012 18:51, insgesamt 4-mal bearbeitet
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wie sollte diese Situation zu Stande kommen? Warum sollte der Benutzer ein Objekt behalten können, wenn er es entfernt?
Aus deiner Erklärung werde ich noch nicht ganz schlau. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Trust |
![]() Antworten mit Zitat ![]() |
---|---|---|
Leite ich eine Klasse von der EngineObjektklasse ab und erstelle ein Objekt, wird dieses automatisch bei dem Aufruf New() in die EngineObjektliste eingetragen.
Bei dem Aufruf der Destroy Methode wird das Objekt aus der EngineObjektliste gelöscht. Die Engine durchgeht intern die Liste und zeichnet nach erfüllten Bedingungen usw. die Objekte ein. Ist das Objekt aber nicht in der Liste, hat die Engine keine Ahnung mer von dem Objekt. Also existiert noch ein Objekt was weder gezeichnet noch geupdatet wird noch sonstwas. Denn der Benutzer hat ja noch die Referenz zu diesem Objekt - nur die Engine nicht. Beispiel: BlitzMax: [AUSKLAPPEN] ' Engine |
||
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen. |
- Zuletzt bearbeitet von Trust am Mo, Mai 28, 2012 19:04, insgesamt einmal bearbeitet
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Warum sollte der Nutzer denn ein Objekt behalten wollen/können?
Entweder es gibt eine klare Beschreibung, wie man mit der Engine umgehen sollte, oder der Nutzer bekommt nie etwas wichtiges in die Finger. Man kann nicht verhindern, dass jemand beliebige Objekte erstellt. Wenn du die Objekte intern verwaltest, gibst du dem Nutzer halt keins. Bestimmte Informationen erbittet man dann und die Engine rückt sie heraus. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Trust |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wie würdest Du das machen?
Sie intern verwalten, oder es dem Benutzer überlassen ( was die Handhabung der Engine dann sicher verkompliziert) [EDIT] Ok ich denke ich versuchs mal anders: Die Engine hat keinen Tau wieviele Objekte existieren, und ich als Nutzer übergebe der Engine einfach nur die Referenz der Objekte die ich einzeichnen will. Wie diese eingezeichnet werden regelt die Engine. So hat der Nutzer volle Kontrolle über alle Objekte die er erstellt. Mal schauen wie das funktioniert. |
||
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen. |
- Zuletzt bearbeitet von Trust am Mo, Mai 28, 2012 19:39, insgesamt einmal bearbeitet
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Je weniger sich der Nutzer kümmern muss und je mehr er sich kümmern kann, desto besser. Die häufigsten Aktionen sollten automatisiert ablaufen, fortgeschrittene Benutzer sollten - wenn sinnvoll - selber herum hantieren können.
Manchmal wäre ein direkter Zugriff einfach schneller, wenn man größere Pläne mit einem Objekt hat. Da musst du wohl selbst Erfahrung sammeln bis du etwas passendes hast. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn ein Nutzer selbst Objekte erstellen kann ist er auch selbst für das entledigen derselben zuständig. So simpel ist das. | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group