【问题标题】:shared_ptr use_count event once a certain value is reached一旦达到某个值,shared_ptr use_count 事件
【发布时间】:2022-12-12 14:57:45
【问题描述】:

为了在内存管理中获得更好的性能(新的 resp.malloc 在我的应用程序中花费了很多时间)我想重用 shared_ptr 包装的对象。

我知道一旦 use_count() 达到某个值就必须删除对象。当前,当 use_count() 等于该值时,我会从容器中删除对象,并在需要时创建新对象。

有没有办法在 use_count() 达到某个值时立即获取事件(函数、lambda 表达式等)? 如果有办法,我可以将对象写在一个列表中以供重用而不是删除。

编辑:我的想法如下 - 快速写下来。

class MyClass {
public:
  MyClass() {};
  virtual ~MyClass() {}
  atomic<shared_ptr<MyClass>> next;
};

// allocate memory quickly in one block
vector<shared_ptr<MyClass>> memory;
memory.reserve(SIZE);
for(unsigned int i = 0; i < SIZE; ++i) memory.emplace_back(make_shared<MyClass>());

atomic<shared_ptr<MyClass>> pool = memory[0];
for(unsigned int i = 0; i < SIZE - 1; ++i) memory[i]->next = memory[i+1];

// object "creation"
shared_ptr<MyClass> create() {
  // here everything should be atomically done
  shared_ptr<MyClass> c = pool;
  pool = c->next;
  return c;
}

// object ready for reuse
void deletion_if_use_count_is_1(shared_ptr<MyClass> d) {
  // here everything should be atomically done
  d->next = pool;
  pool = d;
}

也许有更好的方法来实现这一目标? 但是正如您所见,use_count() 永远不会为 0,但我想重用这些对象;不需要触及 shared_ptr。

【问题讨论】:

  • use_count 的唯一重要值是 0。您可以检测到何时发生,因为指向对象的析构函数将被执行。
  • 一般来说,我不建议重新使用 shared_ptr,而且我认为它们不会被设置为重新初始化(这并不是说不可能)。听起来你应该使用弱指针,这样你就不必在它们的引用计数达到 1 时将它们从你的容器中删除(当它们变得无效时你最终必须处理它们,但内存可以在至少在此期间被释放)。
  • shared_ptr 不提供任何类型的通知机制。您确定shared_ptr 甚至动态分配真的是您的应用程序所需要的吗?
  • 我不太理解“use_count() 达到特定值后立即删除”部分 - shared_ptr 拥有的对象仅应在 use_count == 0 时删除;并且您可以通过提供自定义删除器轻松检测到,然后根据某些条件您可以决定是否删除该对象。另一个问题是您打算如何重用它。
  • 感谢您的回复!我编辑了我的帖子并添加了一些代码。我希望它能更好地理解我想要实现的目标。

标签: c++ memory-management shared-ptr


【解决方案1】:

您可以为 shared_ptr 使用自定义删除器,它实际上不会删除底层对象,而是将其指针插入可重用对象列表中。

您不能使用 make_shared 指定删除器,因此您必须自己编写,例如:

std::shared_ptr<ExpensiveType> make_shared_ExpensiveType(ExpensiveType* expensiveType)
{
    return std::shared_ptr<ExpensiveType>(expensiveType, deleterFunc);
}

【讨论】:

  • 感谢您的回答。我添加了一些代码。我认为我的 use_count 永远不会达到 0 并且永远不会调用标准删除器 - 除非程序结束。
  • 只要您将 shared_ptr 保留在列表中,它就不会达到零。听起来你真正想要的是 weak_ptr 的列表,而不是 shared_ptr
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-30
  • 1970-01-01
  • 1970-01-01
  • 2019-12-02
  • 2022-01-03
  • 2020-10-08
  • 1970-01-01
相关资源
最近更新 更多