How memory is deallocated in shared_ptr via the operator=?

Viewed 275

I am a beginner to c++, I was learning the concept of shared_ptr. I also understood that Several shared_ptr objects may own the same object and the object is destroyed and its memory deallocated when either of the following happens:

1.the last remaining shared_ptr owning the object is destroyed; 2.the last remaining shared_ptr owning the object is assigned another pointer via operator= or reset().

But when I tried to execute a sample program

     class Rectangle { 
        int length; 
        int breadth; 

        public: 
            Rectangle(int l, int b) 
            { 
              length = l; 
              breadth = b; 
            } 

            int area() 
            { 
                return length * breadth; 
            } 
          }; 

          int main() 
         { 

              shared_ptr<Rectangle> P1(new Rectangle(10, 5)); 
              cout << P1->area() << endl; 

              shared_ptr<Rectangle> P2; 
              P2 = P1;  //how is this possible 

             // This'll print 50 
             cout << P2->area() << endl; 

             // This'll now not give an error, 
             cout << P1->area() << endl; 
             cout << P1.use_count() << endl; 
             return 0; 
            } 

After "P2=P1" the memory allocated to P1 has to be deallocated right? But still we can print P1->area(). Please explain how this is happening?

2 Answers

2.the last remaining shared_ptr owning the object is assigned another pointer via operator= or reset().

Yes.

After "P2=P1" the memory allocated to P1 has to be deallocated right?

No. It could happen to P2 if it pointed to something. Not P1.

The logic behind the rule (2) is that the assignment overwrites the value of the first operand, so the first operand will no longer point to what it used to. If it was the last pointer to something, then nothing will point to that anymore, and it can be deleted.

What you learned about destruction of shared pointers is correct. But here, you are not destroying P1. Instead, you are assigning P1 to P2. The implementation of shared_ptr has an overloaded copy assignment operator allowing for this operation and making it correct.

Through that overloaded implementation, P2 is now a shared pointer pointing to the same object as P1 - both pointers access the same object, so you are printing the same areas. Both of them exist in a valid state and as you see, the count of pointers that manage that Rectangle object is 2.

Defining the overloaded = is aligned with the concept of shared_ptr - there are multiple pointers pointing to (owing) the same object. If you want to see a contrasting implementation, look up the unique_ptr - this is a smart pointer that assumes only one pointer has an ownership of the object. It also has an overloaded assignment operator, but using it would invalidate P1 (to my knowledge it would set it to nullptr so it would still be in a valid state, just not pointing to anything). P2 would be the only owner of the Rectangle. Worth trying, for better understanding.

You can find more on the shared_ptr functionality here.

Related