Referenzen auf Gültigkeit prüfen



  • Kann man Referenzen wie Zeiger auf Ihre Gültigkeit prüfen ohne einen Fehler zu erhalten ähnlich wie bei Zeigern? Soweit ich weiss nicht oder?
    Gibts in Boost einen Container dazu der sowas kann? Jemand eine Idee dazu?
    Grund ist, dass ich mehrere Container von std::list habe, die Referenzen aus einer Funktion zurückgeben. Wenn das Objekt aber aus der Liste gelöscht wird, ist die Referenz ungültig. Wie könnte man das lösen ausser Zeiger zu verwenden? Bzw wenn ich Zeiger zurückgebe statt Referenzen wie kann ich sichergehen dass diese nach löschen des Objekts auch auf NULL zeigen und eine Prüfung der Gültigkeit sicher ist?
    rya.



  • Scorcher24 schrieb:

    Kann man Referenzen wie Zeiger auf Ihre Gültigkeit prüfen ohne einen Fehler zu erhalten ähnlich wie bei Zeigern?

    Wie geht das denn mit Zeigern? Mit anderen Worten: Was heißt "gültig" in diesem Kontext?

    Scorcher24 schrieb:

    [...] Wenn das Objekt aber aus der Liste gelöscht wird, ist die Referenz ungültig.

    Aha. Naja, das können Zeiger nicht besser. Die kannst Du auch nicht fragen, ob das, worauf sie zeigen/zeigten, noch da ist.

    Scorcher24 schrieb:

    Bzw wenn ich Zeiger zurückgebe statt Referenzen wie kann ich sichergehen dass diese nach löschen des Objekts auch auf NULL zeigen und eine Prüfung der Gültigkeit sicher ist?

    Gar nicht. Ich glaube, QT hat dafür "schlaue Zeiger", die selbst wissen, wenn sie ungültig geworden sind. Das sind allerdings nur Zeiger-ähnliche Objekte.

    Gruß,
    SP



  • Eine Lösung wären die Smartpointer aus TR1. Aber auch diese können den GAU nicht verhindern. Weil jeder letztendlich doch auf das rohe Objekt mit get() zugreifen kann.

    Deshalb wäre die einzige Möglichkeit, die Objekte zu kapseln, sozusagen in einem Proxy-Objekt... wo der User nicht an die eigentliche Adresse des Objektes kommen kann. Also gehen tut das ganze schon.



  • Wie geht das denn mit Zeigern? Mit anderen Worten: Was heißt "gültig" in diesem Kontext?

    Naja ein Zeiger ist quasi "ungültig" wenn er auf NULL zeigt.. das kann ich prüfen ( er ist schon gültig, aber eben kein Zugriff möglich ). Jeglicher Zugriff auf die Methoden eines Null-Zeigers endet mit einem SIGSEGV. Aber ich kanns ja wie gesagt verhindern indem ich auf NULL prüfe. Vllt umständlich ausgedrückt :D.
    Bei einer Referenz kann ich nur hoffen dass das Objekt auch wirklich noch existiert. Ein Zugriff auf eine Referenz deren Objekt nicht mehr da ist endet mit einem Crash.

    Deshalb wäre die einzige Möglichkeit, die Objekte zu kapseln, sozusagen in einem Proxy-Objekt... wo der User nicht an die eigentliche Adresse des Objektes kommen kann. Also gehen tut das ganze schon.

    Naja, das tu ich ja quasi schon.. ich habe in meinem Game-Framework für jedes Objekt wie Texturen, Fonts etc. einen Manager aus dem ich die Objekte über einen vorher vergebenen Namen anfordern kann oder freigeben kann etc. Die Objekte werden als Referenz zurückgegeben wenn sie gefunden werden. Wird das Objekt nicht gefunden wird ein Fallback-Objekt zurückgegeben, das im Fall der Texturen ein schönes rotes Bild mit enthält wo "replace me" draufsteht und im Fall von Fonts ein Fallback-Font geladen wird etc etc. Also mechanismen um zu gewährleisten, dass das Programm weiterlaufen kann.
    Hab mir jetzt nur darüber Gedanken gemacht, dass das ganze trotzdem Crasht wenn jemand am Spielanfang als Bsp. ein Objekt anfordert, die Referenz speichert und dann nie wieder das Objekt aus den Managern abfragt.
    Aber okay, hier gibts glaube ich keine Lösung.
    Danke trotzdem :).
    rya.



  • Scorcher24 schrieb:

    Naja ein Zeiger ist quasi "ungültig" wenn er auf NULL zeigt.. das kann ich prüfen ( er ist schon gültig, aber eben kein Zugriff möglich ).

    Wenn du einen Null-Zustand brauchst, dann nimm doch Zeiger.

    Jeglicher Zugriff auf die Methoden eines Null-Zeigers endet mit einem SIGSEGV. Aber ich kanns ja wie gesagt verhindern indem ich auf NULL prüfe. Vllt umständlich ausgedrückt :D.
    Bei einer Referenz kann ich nur hoffen dass das Objekt auch wirklich noch existiert. Ein Zugriff auf eine Referenz deren Objekt nicht mehr da ist endet mit einem Crash.

    Das mit der 0 funktioniert aber auch nur, wenn du dem Pointer auch immer brav die 0 zuweist - und wenn du bei jedem Zugriff auf 0 prüfst, sonst crasht es genauso.

    Wird das Objekt nicht gefunden wird ein Fallback-Objekt zurückgegeben, das im Fall der Texturen ein schönes rotes Bild mit enthält wo "replace me" draufsteht und im Fall von Fonts ein Fallback-Font geladen wird etc etc. Also mechanismen um zu gewährleisten, dass das Programm weiterlaufen kann.

    Ich finde das Design sehr fragwürdig. Wenn ich was falsch gemacht habe, möchte ich lieber darauf hingewiesen werden, statt dass das Programm einfach irgendwas macht, nur um weiterlaufen zu können. Es ist auch nicht gerade schön, wenn das Programm an allen Ecken und Enden mit if(bla != 0) zugepflastert wird, damit man auch ja nie auf Nullpointer zugreift. Die Lebensdauer der Objekte sollte geregelt sein, und der Programmierer sollte sie beachten. Tut er es nicht, z. B. indem er Objekte länger behält als er darf, darf es ruhig crashen. Da braucht es keine zig Zeigerprüfungen. Du kannst sowieso nicht alle Dummheiten abfangen, die irgendjemand bauen könnte.

    Aber okay, hier gibts glaube ich keine Lösung.

    Mit Proxy-Objekten geht das schon. Oder mit SmartPointern, die so lange leben, wie sie referenziert werden.



  • Scorcher24 schrieb:

    Naja ein Zeiger ist quasi "ungültig" wenn er auf NULL zeigt.. das kann ich prüfen ( er ist schon gültig, aber eben kein Zugriff möglich ). Jeglicher Zugriff auf die Methoden eines Null-Zeigers endet mit einem SIGSEGV. Aber ich kanns ja wie gesagt verhindern indem ich auf NULL prüfe. Vllt umständlich ausgedrückt :D.
    Bei einer Referenz kann ich nur hoffen dass das Objekt auch wirklich noch existiert. Ein Zugriff auf eine Referenz deren Objekt nicht mehr da ist endet mit einem Crash.

    Genau. Deswegen sollst du auch Zeiger nehmen. Der Einsatz von Referenzen impliziert, dass das referenzierte Objekt gültig ist.

    Scorcher24 schrieb:

    Hab mir jetzt nur darüber Gedanken gemacht, dass das ganze trotzdem Crasht wenn jemand am Spielanfang als Bsp. ein Objekt anfordert, die Referenz speichert und dann nie wieder das Objekt aus den Managern abfragt.
    Aber okay, hier gibts glaube ich keine Lösung.

    Es ist nicht Aufgabe des Bibliothekentwicklers, solche Fehler zu vermeiden. Wenn du in der Dokumentation davon abrätst, Referenzen zwischenzuspeichern (z.B. implizit dadurch, dass das Vorgehen zum Abfragen eines Objekts ein Methodenaufruf deiner Klasse sein muss), reicht das.

    Ich meine, dieses Problem hat man überall. Sieh dir die STL an. Wenn man dort Elemente aus Containern löscht, muss man eben sicherstellen, dass nichts mehr darauf verweist. Man muss sogar bei anderen Operationen sehr vorsichtig sein. Selbst in Java hast du das Problem. Nur lebt dort das Objekt dann weiter, obwohl es nicht mehr gebraucht wird. Da läuft das Programm eben mit einem Logikfehler weiter, in C++ ist das Verhalten undefiniert.



  • Scorcher24 schrieb:

    Wie geht das denn mit Zeigern? Mit anderen Worten: Was heißt "gültig" in diesem Kontext?

    Naja ein Zeiger ist quasi "ungültig" wenn er auf NULL zeigt.. das kann ich prüfen ( er ist schon gültig, aber eben kein Zugriff möglich ).

    Ein Zeiger auf ein Objekt wird aber auch nicht durch magische Hand auf 0 gesetzt, falls man das Objekt " delete t". Referenzen "zeigen" immer auf irgend einen Speicherbereich, weil man sie nicht mit einer "Null-Referenz" initialisieren kann und nach der Initialisierung auch nicht mehr veränderbar sind.

    Aber okay, hier gibts glaube ich keine Lösung.
    Danke trotzdem :).

    Design-Problem. Du musst wissen, was für ein Verhalten Du haben willst. Ein entsprechendes Design gibt es dafür bestimmt.

    Gruß,
    SP


Anmelden zum Antworten