Home > Enterprise >  shared_ptr reference count changed after passed to a unique_ptr object
shared_ptr reference count changed after passed to a unique_ptr object

Time:01-17

I'm fairly new to smart pointers and I couldn't understand the result of the code I attached below. Basically the reference count and the raw pointer it self of a shared_ptr object is changed after it is passed to another unique_ptr object.

So the code goes like this.

typedef shared_ptr<int> sp;                                                        
class bar {                                                                        
 public:                                                                           
  const sp& x; // line 3: if change this line to "const sp x;" then it's fine                                                           
  bar(const sp xx) : x(xx) {                                                       
    cout << "bar:  count=" << x.use_count() << "; addr=" << x.get() << endl;       
  }                                                                                
  void test() {                                                                    
    cout << "test: count=" << x.use_count() << "; addr=" << x.get() << endl;       
  }                                                                                
};                                                                                 
int main() {                                                                       
  auto p = make_shared<int>(0);                                                    
  auto b = make_unique<bar>(p);                                                    
  b->test();                                                                       
}

If I compile and run the code, it prints out:

bar:  count=2; addr=0x557c8b02dec0
test: count=1224736736; addr=0x7ffdb5cbd5c0

So the ref count and pointer are both changed. And it looks like some uninitialized value.

But if I change line 3 to const sp x; then both values look normal:

bar:  count=3; addr=0x5590f026eec0
test: count=2; addr=0x5590f026eec0

Sorry about the bad namings since it's a quick minimum case I came up with to address my question. I feel it has something to do with how unique_ptr works, but I'm not sure.

Can someone shed some light and help me understand why the code behaves like that?

Thanks

CodePudding user response:

Over here:

const sp& x;                                                           
bar(const sp xx) : x(xx)

You assign the shared pointer into a local variable, xx, and then bind the const reference x to that local variable. When the constructor concludes its run, that local variable goes out of scope, leaving you with a reference to Eldritch Horrors and undefined behavior.

To explain your observation regarding the removal of the &:
Removing the & prevents this because in that case you just assign the shared pointer straight into x which henceforth is not dependent on the local variable xx, and so is unaffected by its going out of scope.

To expand: another thing you could do instead, if what you wanted was to hold a reference, is to set xx to be a reference itself (e.g. bar(const sp& xx) : x(xx)); in this case you'd be binding x to p.

  • Related