[boost::shared_ptr] object aus speicherverwaltung entfernen



  • double* b=NULL;
    {
       boost::shared_ptr<double> a(new double);
       b = a.get();
    }
    cout<<*b<<endl;
    

    wie kann ich im scope nun "a" komplett aus der Speicherverwaltung entfernen?
    bei reset() wurde das objekt dahinter gelöscht



  • muffmolch schrieb:

    double* b=NULL;
    {
       boost::shared_ptr<double*> a(new double);
       b = a.get();
    }
    cout<<*b<<endl;
    

    wie kann ich im scope nun "a" komplett aus der Speicherverwaltung entfernen?
    bei reset() wurde das objekt dahinter gelöscht

    Du hast hier schon mehrere Fehler (Wenn man auf einen double zeigen will ist boost::shared_ptr<double> das richtige). Und die Zeile "b = a.get()" ist daher effektiv "double* = double**"...

    Sofern wir das mal abändern auf boost::shared_ptr<double> wird a am Ende seines Scopes gelöscht, daher wäre b bereits ungültig bevor du die Ausgabe überhaupt machst. Mit Glück steht in der Speicherzelle noch der richtige Wert, aber an sich ist der Speicher bereits gelöscht.

    cu André



  • Das was Du da machst ist undefiniertes Verhalten! Nach dem Block ist a nicht mehr existent. Zufällige Daten, die sich noch im Speicher befinden, die man bei dereferenzieren von b erhält, fallen auch unter undefiniertes Verhalten.



  • Ich denke er wollte wissen, wie man genau das verhindert. Das scheint aber wohl nicht zu gehen, eine release-Methode hat das Teil laut Standard nicht.



  • LordJaxom schrieb:

    ...Das scheint aber wohl nicht zu gehen, eine release-Methode hat das Teil laut Standard nicht.

    Zur Ergänzung:

    Die Boost Beschreibung schrieb:

    Q. Why doesn't shared_ptr provide a release() function?

    A. shared_ptr cannot give away ownership unless it's unique() because the other copy will still destroy the object.

    Consider:

    shared_ptr<int> a(new int);
        shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
    
        int * p = a.release();
    
        // Who owns p now? b will still call delete on it in its destructor.
    

    Furthermore, the pointer returned by release() would be difficult to deallocate reliably, as the source shared_ptr could have been created with a custom deleter.

    cu André



  • ja, das mit dem shared:ptr<double*> war natürlich ein schreibfehler (ich habe natürlich auch keine pointer auf doubles gespeichert...). es ging mir tatsächlich nur um die frage, ob es ein release bei boost gibt. den ausschnitt mit dem release habe ich auch gesehen. prinzipiell stimm eich da zu. aber leider ist "release" bei dem code den ich verwende unumgänglich... habe das nun anders gelöst...

    danke dennoch



  • muffmolch schrieb:

    ja, das mit dem shared:ptr<double*> war natürlich ein schreibfehler (ich habe natürlich auch keine pointer auf doubles gespeichert...). es ging mir tatsächlich nur um die frage, ob es ein release bei boost gibt.

    Beim Verlassen des Codeblocks, in dem der Shared_Ptr definiert wurde, wird der Release Count automatisch heruntergezählt. In Deinem Beispiel ist er 0 und dadurch wird auch das allokierte Objekt zerstört. Nur wegen des undefinierten Verhaltens siehst Du außerhalb des Blocks noch etwas. DAS IST ABER EIN PROGRAMMIERFEHLER.



  • habe das nun anders gelöst...

    Würde mich interessieren wie.



  • hustbaer schrieb:

    habe das nun anders gelöst...

    Würde mich interessieren wie.

    Es reicht doch schon, 'd' als 'shared_ptr<double>' zu deklarieren. Easy peasy.



  • Konrad Rudolph schrieb:

    hustbaer schrieb:

    habe das nun anders gelöst...

    Würde mich interessieren wie.

    Es reicht doch schon, 'd' als 'shared_ptr<double>' zu deklarieren. Easy peasy.

    Lol, ja 🙂
    Ich dachte dashier:

    wie kann ich im scope nun "a" komplett aus der Speicherverwaltung entfernen?

    wurde irgendwie gelöst.
    Und da boost::shared_ptr kein "release" kennt...



  • also ich beschreibe es genr nochmal ausführlicher.
    das dumm yprogramm ist natürlich falsch/fehlerhaft/unrichtig und was auch immer.

    aber die frage war eindeutig.

    gerne jetzt nochmal für den interessierten leser etwas ausführlicher.
    ich habe diverse rechenservice am start, die sich "remote" daten übermitteln. das erfolgt mittels RCF. jarl lindrud verwendet hier im hintergrund booss::shared_ptr. dummerweise unterstützten diverse alte codeblöcke diese keine smartpointer oder haben ihre eigenen. daher muss ich auf der "remote" seite die dereferenziereten objekte eben aus der boost: speicherverwaltung entfernen.

    man kann sich das so vorstellen:

    void sendCube(boost::shared_ptr<Cube> ptrCube)
    {
       MySmartPtr<Cube> myPtrCube(ptrCube.get());  
       localModule->setCube(myPtrCube);
    }
    

    erbenis: GAU. nach rückkehr aus der Methode würde der im Speicher initialisierte Cube zerstört werden. Aus diesem Grund wollte ich wissen, ob es irgendwie möglich ist, boost mitzuteilen, dass er das cube-Objekt nicht weiter verwalten soll. nicht mehr und nicht weniger. mir ist klar, dass dies eine unschöne angelegenheit ist, aber eben nicht immer unabdinglich, wenn man verschiedene Codes koppeln möchte. Und die Implementierung einer release-Methode ist trivial. aber da man damit ziemlich viel mist bauen kann, vertehe ich gut, wieso boost diese nicht zur Verfügugn stellt. Aus diesem Grund verschicke ich nun keinen boost::smart_ptr sondern eben bereits einen MySmarPtr oder verwende dort, wo "nackte" Pointer benötigt werden, einen PointerWrapper, der beim Zerstören des Wrappers, zwar den Pointer zerstört, abe reben nicht das eigentliche Objekt. Und ja mir ist bewußt, das sich dadurch die Gefahr erhöht, dass man sich den Speicher zumüllt. Aber keine Sorge, auf jeder Seite fungieren eigene GCs, so dass man lediglich bei Dreizeilern wie oben darauf achten muss, ob man das Objekt in eine neue Verwaltung begibt oder eben nicht. Macht man es nicht, so erfolgt ein "delete" vor Scope Ende...
    Hoffe das war nun ausführlich genug!



  • hustbaer schrieb:

    Konrad Rudolph schrieb:

    hustbaer schrieb:

    habe das nun anders gelöst...

    Würde mich interessieren wie.

    Es reicht doch schon, 'd' als 'shared_ptr<double>' zu deklarieren. Easy peasy.

    Lol, ja 🙂
    Ich dachte dashier:

    wie kann ich im scope nun "a" komplett aus der Speicherverwaltung entfernen?

    wurde irgendwie gelöst.
    Und da boost::shared_ptr kein "release" kennt...

    und genau das sieht man, dass die meisten in die falsch erichtung gedacht haben. das Bsp war nur dazu da um zu zeigen, dass eben genau das verhalten des shared::ptr ausgelöst wird, wenn dieser seinen scope verläßt -> objekt auf das er verweist wird gelöscht, da der interne counter auf 0 gesetzt wird.
    und genau das sollte, wie hustbaer richtig erkannte, vermieden werden. so das zwar der shared_ptr weg ist, nicht aber das eigeneltiche Objekt.

    Zu boost: wem gehört dann das Objekt. hie rbin ich der ansicht, wenn jemand ein objekt aus der verwaltung nimmt, so muss er auch mit den konsequenzen leben, d.h. er muss sicherstellen, dass das objekt: 1. zerstört wird und 2. erst dann, wenn kein weiterer pointer mehr darauf existiert.
    Annahme: simple smart pointer: release entfernt den zugehörigen EINTRAG aus der counter-map -> sobald boost diesen zerstören möchte sieht er, dass er sich gar nicht in der map befindet -> es wird KEIN delete auferufen. alternativ koennte man auch definieren, dass ein release nur dann möglich ich, wenn der ref_count==1 ist. beides, wie gesagt "unschön", aber eine derartige option wäre nicht allzu verkehrt


Anmelden zum Antworten