【问题标题】:nested boost::shared_ptr use_count not updating嵌套 boost::shared_ptr use_count 未更新
【发布时间】:2014-12-22 20:33:23
【问题描述】:

我有一个嵌套的 boost::shared_ptr 在被分配给另一个并超出范围时偶尔会被破坏。我发现除非我将指针复制到临时文件,否则 use_count 不会更新。代码是不言自明的。在第一个 for 循环中,use_count 不更新,而在另一个循环中更新。

#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;
}

输出

使用前的计数:1

使用计数:1

使用前的计数:1

使用计数后:2

【问题讨论】:

    标签: c++ c++11 boost shared-ptr


    【解决方案1】:

    显然,既然您这样做了storage_2d_t storage_2 = storage_1;,将元素直接分配给它们自己不应该增加使用次数。

    在第二个循环中,您在保存临时副本 (ref) 期间打印使用计数。明确地说,您可以看到确实 - 正如预期的那样 - “之后”计数实际上并没有更高:

    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;
    }
    

    现在打印

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

    Live On Coliru


    Brainwave 你的意思是将storage_1 深度克隆到storage_2 中吗?您似乎对您的外部 storage_2d_t 也是一个共享指针这一事实感到困惑,因此您通过引用引用相同的向量。

    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());
    

    【讨论】:

    • 我不想深度克隆共享指针。当调用shared_pointer的浅拷贝构造函数时,我只是增加了use_count。所以你引起了我的注意,这个技巧只是增加了临时副本生命周期的 use_count。那么为什么我在分配 (*storage_2)[i] = (*storage_1)[i] 时不能增加它。这是分配共享指针,必须调用共享指针的复制构造函数,这将增加 (*storage_2)[i] ... 生命周期内的使用计数
    • @mustafabar 你完全错过了我第一句话的重点吗?你不是复制。您将元素分配给自身storage_1storage_2 指向同一个容器
    • 我没有错过你的观点。智能指针复制构造函数本质上是地址的副本,而不是指向数据的深层副本。这应该会增加对这块内存的引用计数,而无需分配新内存。
    • @mustafabar 阅读理解。让我再解释一下:storage_1.get() == storage_2.get() 是真的。因此,(*storage_1)[i].get() == (*storage_2)[i].get() 为真。因此(*storage_2)[i] = (*storage_1)[i]; 没有做任何事情
    • 最终总结:当您将 shared_ptr 复制到 另一个 shared_ptr 时,您可以预期 use_count 会上升。不是当您将其“复制”到自身时。演示:Live On Coliru
    猜你喜欢
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多