Kurze Frage zum shared_ptr Konstruktor



  • Ah, make_shared klingt super! Danke!



  • Zur Not auch ein temporäres shared_ptr Objekt.

    // blabla
    {
        std::shared_ptr<std::mutex> tmp(new std::mutex());
        vec.push_back(tmp);
    }
    // blabla
    

    Aber nicht (!!!) das hier:

    // blabla
    {
        vec.push_back(std::shared_ptr<std::mutex>(new std::mutex()));
    }
    // blabla
    


  • Warum?



  • Das würde mich auch interessieren :>



  • In diesme Fall braucht man make_shared() nicht unbedingt.
    Aber wenn man eine Funktion mit zwei Argumenten hat, von der eine ein shared_ptr ist, könnte es zu einem Memoryleak kommen, da die Auswertungsreihenfolge für Funktionsargumente nicht festgelegt ist. Denn wenn die Erzeugung des zweiten Argumentes eine Exception schmeißt, und von shared_ptr lediglich der new operator aufgerufen wurde, der shared_ptr selber aber noch nicht erzeugt wurde, wird der Destruktor des ptrs nicht aufgerufen und der mit new allokierte Speicher nie freigegeben.



  • Man sollte std::make_shared() auch verwenden, weil es eine Optimierung erlaubt (nämlich Referenz-Counter und Objekt zusammen zu speichern und so nur eine dynamische Allokation zu haben).



  • Denn wenn die Erzeugung des zweiten Argumentes eine Exception schmeißt, und von shared_ptr lediglich der new operator aufgerufen wurde, der shared_ptr selber aber noch nicht erzeugt wurde

    Hmm.

    §5.2.2/8 schrieb:

    The evaluations of the postfix expression and of the argument expressions are all unsequenced relative to one another.

    Aber wie leitest du daraus ab, dass die Auswertung eines Ausdrucks abrupt endet wenn in der Auswertung eines anderen eine Exception geworfen werden soll? Auch wenn die Ausdrücke gleichzeitig ausgewertet werden können,

    §1.9/13 schrieb:

    The execution of unsequenced evaluations can overlap.

    werden sie komplett ausgewertet.





  • krümelkacker schrieb:

    http://herbsutter.com/gotw/_102/

    Bevor noch jemand denkt, dass sein C++ viel schlechter ist als er dachte:

    void f( std::unique_ptr&lt;T1&gt;, std::unique_ptr&lt;T2&gt; );
    

    Das ist kein gültiges C++, auch nicht C++11. Der Mensch kann halt kein HTML (oder mein Browser), das sollte

    void f(std::unique_ptr<T1>, std::unique_ptr<T2>);
    

    heißen 🙄



  • Jetzt wo ich darüber nachdenke hat der Standard meiner Aussage nichts zu bieten. Ich dachte, es steht irgendwo, dass die Auswertung eines Ausdrucks auch definitiv die komplette Auswertung aller Sub-Ausdrücke beinhaltet.



  • Sone schrieb:

    Ich dachte, es steht irgendwo, dass die Auswertung eines Ausdrucks auch definitiv die komplette Auswertung aller Sub-Ausdrücke beinhaltet.

    Hättest nur mal an && und || gedacht. :p



  • out schrieb:

    Sone schrieb:

    Ich dachte, es steht irgendwo, dass die Auswertung eines Ausdrucks auch definitiv die komplette Auswertung aller Sub-Ausdrücke beinhaltet.

    Hättest nur mal an && und || gedacht. :p

    Das meinte ich gar nicht. Ich meinte, dass wenn ein Ausdruck ausgewertet wird, definitiv alles auf einmal ausgewertet wird - sprich, wenn ich schreibe,
    f(g(expr), h(expr2)) , dass dann nicht zuerst expr und danach expr2 ausgewertet wird, sondern sobald die Auswertung von expr angefangen hat, auch g aufgerufen wird und definitiv nichts dazwischen. Dass sozusagen die Auswertung konsistent ist.



  • @Sone
    Ja, das meinen viele. Ist aber in C++ nicht garantiert. Weswegen es auch so wichtig ist immer und immer wieder darauf hinzuweisen.



  • Was sind eigentlich Gründe für sowas?

    Oder allgemeiner gefragt, wieso gibt der Standard nicht Evaluationsreihenfolgen vor?



  • Skym0sh0 schrieb:

    Was sind eigentlich Gründe für sowas?

    Oder allgemeiner gefragt, wieso gibt der Standard nicht Evaluationsreihenfolgen vor?

    Dachte, weil es für den Compiler damit einfacher ist, Optimierungen vorzunehmen.



  • Skym0sh0 schrieb:

    Was sind eigentlich Gründe für sowas?

    Oder allgemeiner gefragt, wieso gibt der Standard nicht Evaluationsreihenfolgen vor?

    Folge krümelkackers Link


Anmelden zum Antworten