1
votes

I have a nested boost::shared_ptr which was occasionally getting destroyed when getting assigned to another one and going out of scope. I figured out that the use_count was not updating unless I copy the pointer to a temp. The code is self-explanatory. In the first for-loop, the use_count doesn't update, whereas it updates on the other.

#include <vector>
#include <boost/shared_ptr.hpp>
#include <iostream>
using namespace std;



int main(int argc, char const *argv[])
{
  typedef int T;
  typedef std::vector<T> content_1d_t;
  typedef boost::shared_ptr<content_1d_t> storage_1d_t;
  typedef std::vector<storage_1d_t> content_2d_t;
  typedef boost::shared_ptr<content_2d_t> storage_2d_t;

  int dim1 = 10;
  int dim2 = 1;
  content_2d_t* content_1 = new content_2d_t();
  content_1->reserve(dim2);
  storage_2d_t storage_1(content_1);

  for (int i = 0; i < dim2; ++i)
  {
    storage_1->push_back(storage_1d_t(new content_1d_t(dim1)));
  }

  //content_2d_t* content_2 = new content_2d_t(dim2);
  storage_2d_t storage_2 = storage_1;

  for (int i = 0; i < dim2; ++i)
  {
    cout<< "use count before : "<< storage_1->operator[](i).use_count()<<endl;
    storage_2->operator[](i) = storage_1->operator[](i);
    cout<< "use count after: "<< storage_1->operator[](i).use_count()<<endl;
  }

  for (int i = 0; i < dim2; ++i)
  {
    cout<< "use count before : "<< storage_1->operator[](i).use_count()<<endl;
    storage_1d_t ref = storage_1->operator[](i);
    storage_2->operator[](i) = ref;
    cout<< "use count after: "<< storage_1->operator[](i).use_count()<<endl;
  }


  /* code */
  return 0;
}

output

use count before : 1

use count after: 1

use count before : 1

use count after: 2

1

1 Answers

3
votes

Since you do storage_2d_t storage_2 = storage_1; obviously, assigning the elements directly back onto themselves should not increase use counts.

I the second loop you print the use count during the time where you hold the temporary copy (ref). Making it explicit, you can see that indeed - as expected - the "after" count is not actually higher:

for (int i = 0; i < dim2; ++i) {
    cout << "use count before : " << (*storage_1)[i].use_count() << endl;
    {
        storage_1d_t ref = (*storage_1)[i];
        (*storage_2)[i] = ref;
        cout << "use count during: " << (*storage_1)[i].use_count() << endl;
    }
    cout << "use count after: " << (*storage_1)[i].use_count() << endl;
}

Now prints

use count before : 1
use count during: 2
use count after: 1

See it Live On Coliru


Brainwave Did you mean to deep-clone storage_1 into storage_2? It appears you have been confused by the fact that your outer storage_2d_t is also a shared pointer and hence you refer to the same vector by reference.

storage_2d_t storage_2 = boost::make_shared<content_2d_t>(*storage_1);
// or
storage_2d_t storage_2 = boost::make_shared<content_2d_t>(storage_1->begin(), storage_1->end());