如何从boost :: shared_ptr释放指针?

use*_*508 39 c++ boost shared-ptr

boost :: shared_ptr可以释放存储的指针而不删除它吗?

我可以看到文档中没有发布功能,也在FAQ中解释了为什么它不提供发布功能,类似于发布不能在不唯一的指针上完成.我的指针是独一无二的.我该如何发布我的指针?或者哪个提升智能指针类使用,这将允许我释放指针?我希望你不要说使用auto_ptr :)

sel*_*tze 29

别.Boost的FAQ条目:

Q.为什么shared_ptr不提供release()函数?

.shared_ptr不能放弃所有权,除非它是唯一的()因为另一个副本仍将销毁该对象.

考虑:

shared_ptr<int> a(new int);
shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2

int * p = a.release();

// Who owns p now? b will still call delete on it in its destructor.
Run Code Online (Sandbox Code Playgroud)

此外,release()返回的指针很难可靠地解除分配,因为源shared_ptr可能是使用自定义删除器创建的.

因此,如果它是唯一指向您的对象的shared_ptr实例(当unique()返回true时)并且该对象不需要特殊的删除器,这将是安全的.如果您使用了这样的.release()函数,我仍然会质疑您的设计.

  • 理想情况下,只有在use_count()== 1时,释放才会成功.这样可行.:| (3认同)

Kir*_*sky 22

你可以使用假删除器.然后指针实际上不会被删除.

struct NullDeleter {template<typename T> void operator()(T*) {} };

// pp of type some_t defined somewhere
boost::shared_ptr<some_t> x(pp, NullDeleter() );
Run Code Online (Sandbox Code Playgroud)

  • 这很有意思,但首先使用shared_ptr的目的是什么? (6认同)
  • @UncleBens,这种删除器的使用非常有限。例如,当你需要调用一个函数并传递给它类似`shared_ptr&lt;some_t&gt;( this )` 的东西时。只有使用“NullDeleter”才会安全。 (2认同)

cur*_*guy 7

孩子们,不要在家里这样做:

// set smarty to point to nothing
// returns old(smarty.get())
// caller is responsible for the returned pointer (careful)
template <typename T>
T* release (shared_ptr<T>& smarty) {
    // sanity check:
    assert (smarty.unique());
    // only one owner (please don't play games with weak_ptr in another thread)
    // would want to check the total count (shared+weak) here

    // save the pointer:
    T *raw = &*smarty;
    // at this point smarty owns raw, can't return it

    try {
        // an exception here would be quite unpleasant

        // now smash smarty:
        new (&smarty) shared_ptr<T> ();
        // REALLY: don't do it!
        // the behaviour is not defined!
        // in practice: at least a memory leak!
    } catch (...) {
        // there is no shared_ptr<T> in smarty zombie now
        // can't fix it at this point:
        // the only fix would be to retry, and it would probably throw again
        // sorry, can't do anything
        abort ();
    }
    // smarty is a fresh shared_ptr<T> that doesn't own raw

    // at this point, nobody owns raw, can return it
    return raw;
}
Run Code Online (Sandbox Code Playgroud)

现在,有没有办法检查引用计数的所有者总数是否> 1?

  • +1提供问题的答案,可惜没有更好的方法. (2认同)
  • 让我指出这个解决方案的两个严重问题: 1&gt; 如果你使用了 `make_shared` 那么 `release` 将不会返回一个可以与 `delete` 一起使用的指针,因为 `make_shared` 分配内存的方式。2&gt; `weak_ptr` 通常使用订阅模式,因此如果您不运行 `shared_ptr` 析构函数,`weak_ptr` 的 `lock()` 方法将返回一个有效的 `shared_ptr` ,它再次拥有内存。但它可能不会删除它,因为引用计数现在减少了 1。 (2认同)

Mar*_* Ba 6

您需要使用可以请求不删除基础指针的删除器.

有关详细信息,请参阅此答案(已标记为此问题的副本).