Home > Software engineering >  shared_ptr doesn't increase reference count, but point at the same address
shared_ptr doesn't increase reference count, but point at the same address

Time:03-03

here is my code snippet:

#include <iostream>
#include <list>
#include <memory>

class A
{

 public:

  int a = 100;

  A()
  {
    std::cout << "Create A" << std::endl;
  }

  ~A()
  {
    std::cout << "Release A" << std::endl;
  }

  virtual void printer() = 0;

};

std::list<std::shared_ptr<A>> arr;

class B : public A
{

 public:

  int b = 1000;

  ~B()
  {
    std::cout << "Release B" << std::endl;
  }

  void printer() override
  {
    std::cout << "B's printer" << std::endl;
  }

  B()
  {
    std::shared_ptr<A> tmp(this);
    arr.push_back(tmp);
    (*arr.begin())->printer();
    std::cout << "inside B's c'tor test B counts: " << tmp.use_count()
              << std::endl;
  }

};

int main(int argc, char const *argv[])
{
  std::shared_ptr<B> B_ptr = std::make_shared<B>();
  std::shared_ptr<A> A_ptr(B_ptr);
  std::cout << "list address:  " << (*arr.begin()).get() << std::endl;
  std::cout << "test B address: " << B_ptr.get() << std::endl;
  std::cout << "test A address: " << A_ptr.get() << std::endl;

  std::cout << "list counts:  " << (*arr.begin()).use_count() << std::endl;
  std::cout << "test B counts: " << B_ptr.use_count() << std::endl;
  std::cout << "test A counts: " << A_ptr.use_count() << std::endl;
  return 0;
}

My expectation is: A's reference count should be three, but only got 2. I think when I push_back to the list, there should be a temporarily created share_ptr object, even it is get destroyed, the one in list should also pointing to the same address as A_ptr and B_ptr. It turns out that they (those three), did pointing at the same address, but use_count got different results. (*arr.begin()).use_count() is 1, the others are both 2.

Why? Please help.

Ps: I know turning this pointer to share_ptr is stupid operation, but the result doesn't make sense and even disobey the syntax.

CodePudding user response:

My expectation is: A's reference count should be three, but only got 2.

Your expectation is wrong. You only made one copy of the shared pointer, so the use count is 2.

std::shared_ptr<A> tmp(this);

On this line you transfer the ownership of a bare pointer that you don't own into a new shared pointer. Since this was already owned by another shared pointer, the behaviour of the program will be undefined when the two separate owners attempt to destroy it.


Creating a shared pointer from this is possible using std::enable_shared_from_this, but it's not simple.

  • Related