Fragen zum std::shared_ptr / std::unique_ptr



  • Hallo Leute,

    Ich möchte jetzt mal den std::shared_ptr verwenden, habe aber noch meine Probleme damit. Soweit ich weiß bietet dieser den Vorteil, dass ich auf den allozierten Speicher nicht mehr aufpassen muss (was das delete angeht).

    Ich habe folgende Fälle:

    // Fall 1: klassisch, OK
    unsigned char *buffer1 = nullptr;
    // ...irgendwelcher code...
    buffer1 = new unsigned char[100]();
    // ...irgendwelcher code...
    delete[] buffer1;
    
    // Fall 2: klassisch, OK
    unsigned char *buffer2 = new unsigned char[100]();
    // ...irgendwelcher code...
    delete[] buffer2;
    
    // Fall 3: OK
    std::shared_ptr<unsigned char> buffer3 (new unsigned char[100]());
    // ...irgendwelcher code...
    
    // Fall 4: Fehler
    std::shared_ptr<unsigned char> buffer4 = nullptr;
    // ...irgendwelcher code...
    buffer4 = new unsigned char[100]();  //error
    // ...irgendwelcher code...
    

    Fall 1 und 2 sind die Varianten, die ich bisher so kenne und anwende. Wie muss ich es umbauen, damit ein std::shared pointer daraus wird? Fall 3 schein schon mal so zu klappen, aber Fall 4 schmeißt einen Fehler.

    Sollte man außerdem lieber einen std::unique_ptr verwenden, wenn man den Pointer nicht 'herumreicht'? Kann ich den shared_ptr auch als Parameter verwenden,in dem ein 'unsigned char*' verlangt wird (geht das dann mit buffer3.get())?

    viele Grüße,
    SBond



  • Fall 3: leckt (google: shared_ptr array - EDIT: Oder um es dir abzunehmen: http://stackoverflow.com/questions/13061979/shared-ptr-to-an-array-should-it-be-used)
    EDIT: (weil delete verwendet wird, nicht delete[] - außer man ändert den deleter)

    Fall 4: reset.

    EDIT: Ich ignoriere wiedermal, dass es shared_array gibt, oder vector<...>*

    EDIT:

    std::unique_ptr verwenden, wenn man den Pointer nicht 'herumreicht'? Kann ich den shared_ptr auch als Parameter verwenden,in dem ein 'unsigned char*' verlangt wird

    ein unique_ptr ist ist erstmal immer die richtige Wahl. shared_ptr merkt man wenn man den braucht.
    EDIT: Und unique_ptr hat eine Spezialisierung für array deleter:

    std::unique_ptr <const char[]> juhu;
    

    und ja .get() wäre die richtige Wahl.
    btw: shared_ptr nur als Parameter übergeben, wenn die Lebenszeit mit übergeben werden muss. Das passiert eigentlich AFAIK nur in multi-threading Kontexten.

    EDIT: Ich hoffe der Beitrag wirkt durch die ganzen Edits nicht zerflückt...



  • Grundsätzlich immer unique_ptr vor shared_ptr ziehen. Auch beachten, dass Smartpointer die 'Objektbesitzer' sind, also das besitzte Objekt löschen. Willst du den Besitz nicht weiterreichen, benutze auch keine Smartpointer, sondern Referenzen und Zeiger, willst du das Objekt an Funktionen etc weiterreichen.



  • Danke für die Hilfe 🙂



  • std::unique_ptr <const char[]>

    Wobei das in der Praxis nur selten Sinn macht ...
    std::vector<char> als verwaltungsobjekt inklusive besitz- und Move- Semantik reicht meist aus ... einziger unterschied ist halt die standardmäßige tiefe Kopie, was man anderweitig umgehen kann/muss ...
    für einzelne Objekte hingegen ist er natürlich ideal.

    shared_ptr ist nen anderes Thema, weil man da die referenzzählung bekommt(wenn man sicher ist das man die braucht ...)

    Ciao ...


Log in to reply