Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. unique_ptr reset problem

unique_ptr reset problem

Scheduled Pinned Locked Moved C++ Gurus
11 Posts 4 Posters 7.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    ceora
    wrote on 3 Jun 2015, 11:35 last edited by ceora 6 Mar 2015, 11:44
    #1

    I have some problem with unique_ptr.reset(): when i pass a pointer to reset(so unique_ptr take ownership of it) it doesn't reset the source pointer. This cause the pointer to not be unique.

    std::unique_ptr<TestClass> ptr;
    TestClass *testClass= new TestClass ;
    ptr.reset(testClass);
     //testClass is still valid, should be nullptr now...
    

    from the <memory> header file reset() doesn't set nothing to nullptr

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mcosta
      wrote on 3 Jun 2015, 11:47 last edited by mcosta 6 Mar 2015, 11:49
      #2

      Hi,

      is not correct; in this case you set testClass as managed by ptr.
      You'll have testClass set to nullptr if you now do something like

      ptr.reset();
      

      or

      TestClass *newPointer = new TestClass;
      ptr.reset(newPointer);
      

      Read here for more info.

      Once your problem is solved don't forget to:

      • Mark the thread as SOLVED using the Topic Tool menu
      • Vote up the answer(s) that helped you to solve the issue

      You can embed images using (http://imgur.com/) or (http://postimage.org/)

      1 Reply Last reply
      0
      • C Offline
        C Offline
        ceora
        wrote on 3 Jun 2015, 11:59 last edited by
        #3

        so how i can transfer ownership to unique_ptr?? basically what i want to achieve is to avoid to passing unique_ptr around, for example in a tree structure.

        M 1 Reply Last reply 3 Jun 2015, 12:53
        0
        • C ceora
          3 Jun 2015, 11:59

          so how i can transfer ownership to unique_ptr?? basically what i want to achieve is to avoid to passing unique_ptr around, for example in a tree structure.

          M Offline
          M Offline
          mcosta
          wrote on 3 Jun 2015, 12:53 last edited by
          #4

          @ceora said:

          so how i can transfer ownership to unique_ptr??

          using unique_ptr::reset(newPointer) you pass the ownership to it.
          If you need to pass that pointer to functions or containers you could use std::shared_ptr

          Once your problem is solved don't forget to:

          • Mark the thread as SOLVED using the Topic Tool menu
          • Vote up the answer(s) that helped you to solve the issue

          You can embed images using (http://imgur.com/) or (http://postimage.org/)

          1 Reply Last reply
          0
          • S Offline
            S Offline
            stereomatchingkiss
            wrote on 4 Jun 2015, 06:00 last edited by stereomatchingkiss 6 Apr 2015, 06:02
            #5

            @ceora already answer you, I would add more details about it.

            The responsible of std::unique_ptr is help you manage the life time of the resource(I say resource, not memory because it can handle more than that).

            Basically, the api reset will reset the pointer hold by the unique_ptr
            Solution 1 :

            auto test_class = new TestClass;
            std::unique_ptr<TestClass> ptr(test_class ); //let the unique_ptr handle the resource--test_class
            ptr.reset(nullptr); //set the resource handle by the unique_ptr to nullptr
            

            Could we initialize the unique_ptr with better solution?Yes
            Solution 2 :

            std::unique_ptr<TestClass> ptr(new TestClass); 
            

            Is it possible to make it even better?Yes
            Solution 3 :

            auto ptr = std::make_unique<TestClass>(); //need c++14
            

            If you cannot wait until most of the compiler to support c++14, you can implement it by yourself

            template<typename T, typename... Args>
            std::unique_ptr<T> make_unique(Args&&... args)
            {
                return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
            }
            

            What are the benefits of using make_unique?

            1 : it makes your codes more compact
            2 : it helps you avoid the trap of "resource leak"

            suppose you have an api which accept std::unique_ptr<TestClass> as following

            void do_something(std::unique_ptr<TestClass> lhs, std::unique_ptr<TestClass> rhs)
            {
                //.........
            }
            

            If you call it like this

            do_something(std::unique_ptr<TestClass>(new TestClass), std::unique_ptr<TestClass>(new TestClass));
            

            The memory may leak if one of the construction fail(for details, please study effective c++ or effective modern c++)

            @If you need to pass that pointer to functions or containers you could use std::shared_ptr
            Not really, you can pass by pointer, pass by reference or move it.

            (1) pass by pointer

            void do_something(TestClass *ptr);
            

            (2) pass by reference

            void do_something(std::unique_ptr<TestClass> &ptr);
            

            (3) move it

            void do_something(std::unique_ptr<TestClass> ptr);
            

            you can move it as following

            auto ptr = std::make_unique<TestClass>();
            do_something(std::move(ptr));
            

            or

            do_something(std::make_unique<TestClass>());
            

            I prefer solution (1) since that api is more flexible(do not bound to particular smart pointer).
            Raw pointer is not ideal at resource management but very good at access resource

            In my humble opinion, the objective of std::shared_ptr is sharing the resource
            It is much harder to predict the life time of the shared_ptr, and it is also more expensive than
            the zero performance penalty unique_ptr.Besides, unique_ptr could show you that this is a unique resource

            1 Reply Last reply
            0
            • C Offline
              C Offline
              ceora
              wrote on 4 Jun 2015, 07:37 last edited by
              #6

              @stereomatchingkiss thanks for the explanation! How I can find out when using shared_ptr, unique_ptr or raw pointer, ore better when resource can be considered shared or as visitors (using the pointer, look at the data, ..)? if pointer are mostly used for data sharing(for allocation are better containers), when use unique_ptr instead of non pointer variable? Another problem is debugging smart pointer, they aren't deferenced making them hard to read..

              K 1 Reply Last reply 4 Jun 2015, 08:03
              0
              • C ceora
                4 Jun 2015, 07:37

                @stereomatchingkiss thanks for the explanation! How I can find out when using shared_ptr, unique_ptr or raw pointer, ore better when resource can be considered shared or as visitors (using the pointer, look at the data, ..)? if pointer are mostly used for data sharing(for allocation are better containers), when use unique_ptr instead of non pointer variable? Another problem is debugging smart pointer, they aren't deferenced making them hard to read..

                K Offline
                K Offline
                koahnig
                wrote on 4 Jun 2015, 08:03 last edited by
                #7

                @ceora

                shared_ptr::use_count() helps for knowning if there are other instances sharing this memory.
                The debugging of smart pointers may be an issue of the debugger used. The main problem, I see, is that there is an extra layer in between, which makes debugging less intuitive. However, this is the little pain you have to accept with the comfort and advantages of smartpointers. Besides the additional layer there is no other problem in debugging.

                Vote the answer(s) that helped you to solve your issue(s)

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  stereomatchingkiss
                  wrote on 4 Jun 2015, 09:01 last edited by
                  #8

                  @ceora koahnig already answer your question

                  How I can find out when using shared_ptr, unique_ptr or raw pointer
                  Before I answered you this question, I would like to say the best way(maybe) is "do not use any pointer, put your resource on stack".

                  Example:

                  void MainWindow::closeEvent(QCloseEvent *event)
                  {
                      QSettings setting{"ThamSoftWare", "QRenamer"};
                      setting.setValue("geometry", saveGeometry());
                  
                      event->accept();
                  }
                  

                  Is easier to deal and more efficient than(because you save the cost of allocate memory on heap)

                  void MainWindow::closeEvent(QCloseEvent *event)
                  {
                      auto setting = std::make_unique<QSettings>{"ThamSoftWare", "QRenamer"};
                      setting->setValue("geometry", saveGeometry());
                  
                      event->accept();
                  }
                  

                  If you just need a local object to do some job, rather than new it and put it into smart pointer, just create it on stack(someone call them auto object?).

                  As far as I know, if you do not need to shared the resource, then you do not need the shared_ptr.You could think it like this way too, if stack work for you, do not use unique_ptr, if unique_ptr works for you, do not use shared_ptr, treat shared_ptr as the last resort.

                  I never have any real life experience when shared_ptr is a much better solution than scope object on stack or unique_ptr, so the following example may look fake(pseudo codes).

                  Assuming you are design a game, the game have a monster which could spawn themselves(slime)
                  Even the slime can spawn, all of the slime share some common state(mp, hp or other's) and some
                  different states.

                  class slime_state
                  {
                      public:
                     //......some states
                  }
                  
                  class slime
                  {
                    public:
                    //some operations
                    private:
                       std::shared_ptr<slime_state> states_;
                  }
                  

                  In this kind of situation, you may want to create many slime with same states_ and do not want to bother to delete the slime_state when the last slime die. This maybe a good situation to give shared_ptr a try.

                  For more details, you can study "The c++ programming language, 4th"

                  Another problem is debugging smart pointer, they aren't deferenced making them hard to read..
                  I seldom use the debug mode to debug, so I cannot give you much suggestion about that, sorry

                  K 1 Reply Last reply 4 Jun 2015, 10:00
                  0
                  • S stereomatchingkiss
                    4 Jun 2015, 09:01

                    @ceora koahnig already answer your question

                    How I can find out when using shared_ptr, unique_ptr or raw pointer
                    Before I answered you this question, I would like to say the best way(maybe) is "do not use any pointer, put your resource on stack".

                    Example:

                    void MainWindow::closeEvent(QCloseEvent *event)
                    {
                        QSettings setting{"ThamSoftWare", "QRenamer"};
                        setting.setValue("geometry", saveGeometry());
                    
                        event->accept();
                    }
                    

                    Is easier to deal and more efficient than(because you save the cost of allocate memory on heap)

                    void MainWindow::closeEvent(QCloseEvent *event)
                    {
                        auto setting = std::make_unique<QSettings>{"ThamSoftWare", "QRenamer"};
                        setting->setValue("geometry", saveGeometry());
                    
                        event->accept();
                    }
                    

                    If you just need a local object to do some job, rather than new it and put it into smart pointer, just create it on stack(someone call them auto object?).

                    As far as I know, if you do not need to shared the resource, then you do not need the shared_ptr.You could think it like this way too, if stack work for you, do not use unique_ptr, if unique_ptr works for you, do not use shared_ptr, treat shared_ptr as the last resort.

                    I never have any real life experience when shared_ptr is a much better solution than scope object on stack or unique_ptr, so the following example may look fake(pseudo codes).

                    Assuming you are design a game, the game have a monster which could spawn themselves(slime)
                    Even the slime can spawn, all of the slime share some common state(mp, hp or other's) and some
                    different states.

                    class slime_state
                    {
                        public:
                       //......some states
                    }
                    
                    class slime
                    {
                      public:
                      //some operations
                      private:
                         std::shared_ptr<slime_state> states_;
                    }
                    

                    In this kind of situation, you may want to create many slime with same states_ and do not want to bother to delete the slime_state when the last slime die. This maybe a good situation to give shared_ptr a try.

                    For more details, you can study "The c++ programming language, 4th"

                    Another problem is debugging smart pointer, they aren't deferenced making them hard to read..
                    I seldom use the debug mode to debug, so I cannot give you much suggestion about that, sorry

                    K Offline
                    K Offline
                    koahnig
                    wrote on 4 Jun 2015, 10:00 last edited by
                    #9

                    @stereomatchingkiss
                    shared_ptr are good when have a container holding the shared_ptr, but you need to update while the actual object is still in use.
                    E.g. you change the properties of an object by placing a new pointer and removing the old one. When the object is still used somewhere, this routine can be completed without side effects. For such reasons I am using shared_ptr very often. In real-time apps the primary owner cannot always wait until the each subs are finished. Otherwise I would have to do all the book-keeping myself.

                    I have never used a unique_ptr so far.

                    At least on windows through Qt creator with MinGW the debugging has no major disadvantges besides the additional layer. IIRC also under Ubuntu it did work in the same manor.

                    Vote the answer(s) that helped you to solve your issue(s)

                    C 1 Reply Last reply 4 Jun 2015, 13:51
                    0
                    • K koahnig
                      4 Jun 2015, 10:00

                      @stereomatchingkiss
                      shared_ptr are good when have a container holding the shared_ptr, but you need to update while the actual object is still in use.
                      E.g. you change the properties of an object by placing a new pointer and removing the old one. When the object is still used somewhere, this routine can be completed without side effects. For such reasons I am using shared_ptr very often. In real-time apps the primary owner cannot always wait until the each subs are finished. Otherwise I would have to do all the book-keeping myself.

                      I have never used a unique_ptr so far.

                      At least on windows through Qt creator with MinGW the debugging has no major disadvantges besides the additional layer. IIRC also under Ubuntu it did work in the same manor.

                      C Offline
                      C Offline
                      ceora
                      wrote on 4 Jun 2015, 13:51 last edited by
                      #10

                      @koahnig
                      From what i heard from Herb Sutter conf, it's better to always use unique_ptr if you don't know if resource will be shared, cause shared_ptr are less efficient (because thy keep a reference count), also it's better to don't pass smart pointer around unless you want express the intention to pass ownership. My problem is that i want to optimize code before write it XD. However if i want go for sure i think i will always use shared_ptr too...

                      For the debugging problem, is the additional layer that make hard to read for me, i would like to have data well presented so i can look fast at them, without expand too many tree elements in debug view.

                      K 1 Reply Last reply 4 Jun 2015, 14:21
                      0
                      • C ceora
                        4 Jun 2015, 13:51

                        @koahnig
                        From what i heard from Herb Sutter conf, it's better to always use unique_ptr if you don't know if resource will be shared, cause shared_ptr are less efficient (because thy keep a reference count), also it's better to don't pass smart pointer around unless you want express the intention to pass ownership. My problem is that i want to optimize code before write it XD. However if i want go for sure i think i will always use shared_ptr too...

                        For the debugging problem, is the additional layer that make hard to read for me, i would like to have data well presented so i can look fast at them, without expand too many tree elements in debug view.

                        K Offline
                        K Offline
                        koahnig
                        wrote on 4 Jun 2015, 14:21 last edited by
                        #11

                        @ceora
                        However, that is exactly the place where I am using the shared_ptr. I have a central container holding information which is required by other parts of the SW. The information will change once in a while, but the already started calculations cannot be stopped, but have to be finished with the very same information in all places. Therefore, I could do only an update when all calculations have been done. However, this point I might have to start the next one already. Certainly I could do all this without using a standard shared_ptr, but at day's end I would probably add a similar and more time-consuming functionality.

                        The additional layer is basically and two additonal clicks (IIRC) in the debug window. Makes tghe window a bit bigger, but that's it.

                        Certainly shared_ptr are not a good solution everywhere. Because of overhead they should be used only where required.

                        Vote the answer(s) that helped you to solve your issue(s)

                        1 Reply Last reply
                        0

                        9/11

                        4 Jun 2015, 10:00

                        • Login

                        • Login or register to search.
                        9 out of 11
                        • First post
                          9/11
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved