如何释放从boost :: shared_ptr的指针?(How to release pointe

2019-07-21 02:40发布

可以提高:: shared_ptr的释放所储存的指针,而不删除它?

我可以看到文档中没有释放函数存在,也是在帮助解释为什么它不提供释放功能,类似的东西释放不能说不是唯一的指针来完成。 我的指针是唯一的。 我怎样才能释放我的指点? 或提高智能指针类使用,让我释放的指针? 我希望你不会说使用auto_ptr :)

Answer 1:

你需要使用一个删除器,你可以要求不删除基础指针。

看到这个答案 (这已被标记为这个问题的副本)了解更多信息。



Answer 2:

别。 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. 

此外,通过释放返回的指针()将难以可靠地解除分配,作为源shared_ptr的可能已被使用定制删除创建的。

因此,在情况下,它是唯一的shared_ptr实例指向你的对象(唯一在()返回true)和对象不需要特殊缺失者,这将是安全的。 我仍然怀疑你的设计,如果你使用了这样的.release()函数。



Answer 3:

你可以使用假货缺失者。 然后,指针不会被真正删除。

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

// pp of type some_t defined somewhere
boost::shared_ptr<some_t> x(pp, NullDeleter() );


Answer 4:

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

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

现在,有一种方法来检查,如果对于裁判的计数业主总数为> 1?



Answer 5:

要再次让指针指向什么,可以调用shared_ptr::reset()

然而,这将删除指向的对象,当你的指针是最后的参考对象。 然而,这也正是摆在首位的智能指针的期望的行为。

如果你只是想不持有对象活着的引用,你可以创建一个boost::weak_ptr (见Boost文档 )。 一个weak_ptr持有对象的引用,但不会增加引用计数,因此当只有弱引用存在的对象被删除。



Answer 6:

共享的基础是信任。 如果在你的程序某些情况下需要释放原始指针,它几乎可以肯定的是shared_ptr是错误的类型。

然而,最近我想就此别过,因为我需要从一个不同的进程堆解除分配。 在最后,我被教导说,我的大决定使用一些std::shared_ptr当时也没想出。

我只是经常使用这种类型的清理。 但指针只是复制在几个地方。 其实我需要std::unique_ptr ,其中(惊喜)有一个release的功能。



Answer 7:

原谅他们吧,他们不知道他们做什么。 本例将升压:: shared_ptr的和MSVS的std :: shared_ptr的没有内存泄漏!

template <template <typename> class TSharedPtr, typename Type>
Type * release_shared(TSharedPtr<Type> & ptr)
{
    //! this struct mimics the data of std:shared_ptr ( or boost::shared_ptr )
    struct SharedVoidPtr
    {
        struct RefCounter
        {
            long _Uses;
            long _Weaks;
        };

        void * ptr;
        RefCounter * refC;

        SharedVoidPtr()
        {
            ptr = refC = nullptr;
        }

        ~SharedVoidPtr()
        {
            delete refC;
        }
    };

    assert( ptr.unique() );

    Type * t = ptr.get();

    SharedVoidPtr sp; // create dummy shared_ptr
    TSharedPtr<Type> * spPtr = (TSharedPtr<Type>*)( &sp );
    spPtr->swap(ptr); // swap the contents

    ptr.reset();
    // now the xxx::shared_ptr is empy and
    // SharedVoidPtr releases the raw poiter but deletes the underlying counter data
    return t;
}


Answer 8:

您可以删除共享指针,这似乎大同小异给我。 如果指针始终是唯一的,然后std::auto_ptr<>是一个不错的选择。 请记住,唯一的指针不能在STL容器中使用,因为它们的操作做了很多拷贝和临时复制的。



Answer 9:

我不能完全肯定,如果你的问题是关于实现这一目标,但如果你从想要的行为shared_ptr ,在这里,如果你从一个释放价值shared_ptr ,其他所有的共享指针为相同的值成为nullptr,那么你就可以放unique_ptrshared_ptr实现这一行为。

void print(std::string name, std::shared_ptr<std::unique_ptr<int>>& ptr)
{
    if(ptr == nullptr || *ptr == nullptr)
    {
        std::cout << name << " points to nullptr" << std::endl;
    }
    else
    {
        std::cout << name << " points to value " << *(*ptr) << std::endl;
    }
}

int main()
{
    std::shared_ptr<std::unique_ptr<int>> original;
    original = std::make_shared<std::unique_ptr<int>>(std::make_unique<int>(50));

    std::shared_ptr<std::unique_ptr<int>> shared_original = original;

    std::shared_ptr<std::unique_ptr<int>> thief = nullptr;

    print(std::string("original"), original);
    print(std::string("shared_original"), shared_original);
    print(std::string("thief"), thief);

    thief = std::make_shared<std::unique_ptr<int>>(original->release());

    print(std::string("original"), original);
    print(std::string("shared_original"), shared_original);
    print(std::string("thief"), thief);

    return 0;
}

输出:

original points to value 50
shared_original points to value 50
thief points to nullptr
original points to nullptr
shared_original points to nullptr
thief points to value 50

这种行为可以让你分享的资源(如数组),然后再重复使用资源,而所有无效对该资源的共享引用。



Answer 10:

下面是可能工作黑客攻击。 除非你在一个真正的绑定是我不会推荐它。

template<typename T>
T * release_shared(std::shared_ptr<T> & shared)
{
    static std::vector<std::shared_ptr<T> > graveyard;
    graveyard.push_back(shared);
    shared.reset();
    return graveyard.back().get();
}


Answer 11:

如果你的三分球确实是唯一不使用std::unique_ptrboost::scoped_ptr ,如果前者不适用于你的编译器。 否则,考虑结合使用boost::shared_ptrboost::weak_ptr 。 退房Boost文档了解详情。



Answer 12:

我使用波科:: HTTPRequestHandlerFactory它期望返回原始HTTPRequestHandler *中,波科框架删除处理程序一旦请求完成。

还使用DI酱项目以创建控制器,但是进样器返回的shared_ptr我不能直接返回,返回handler.get()是没有好或者因为只要这个函数返回的shared_ptr超出范围,然后删除处理程序其执行之前,所以这里是一个合理的(我认为)的理由有.release()方法。 我结束了创建一个HTTPRequestHandlerWrapper类如下: -

class HTTPRequestHandlerWrapper : public HTTPRequestHandler {
private:
    sauce::shared_ptr<HTTPRequestHandler> _handler;

public:
    HTTPRequestHandlerWrapper(sauce::shared_ptr<HTTPRequestHandler> handler) {
        _handler = handler;
    }

    virtual void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) {
        return _handler->handleRequest(request, response);
    }
};

然后工厂将

HTTPRequestHandler* HttpHandlerFactory::createRequestHandler(const HTTPServerRequest& request) {
    URI uri = URI(request.getURI());
    auto path = uri.getPath();
    auto method = request.getMethod();

    sauce::shared_ptr<HTTPRequestHandler> handler = _injector->get<HTTPRequestHandler>(method + ":" + path);

    return new HTTPRequestHandlerWrapper(handler);
}

这既满足了酱和波科和很好地工作。



Answer 13:

我需要通过异步处理程序传递一个指针,以保持自毁行为的情况下,失败的,但最终的API预期原始指针,所以我做了这个功能从单一的shared_ptr释放:

#include <memory>

template<typename T>
T * release(std::shared_ptr<T> & ptr)
{
    struct { void operator()(T *) {} } NoDelete;

    T * t = nullptr;
    if (ptr.use_count() == 1)
    {
        t = ptr.get();
        ptr.template reset<T>(nullptr, NoDelete);
    }
    return t;
}

如果ptr.use_count() != 1 ,你应该得到一个nullptr来代替。



Answer 14:

简单的解决方案,增加参考,然后泄漏shared_pointer。

boost::shared_ptr<MyType> shared_pointer_to_instance(new MyType());
new boost::shared_ptr<MyType>();
MyType * raw_pointer = shared_pointer_to_instance.get()

这显然会导致两个shared_ptr的的内存泄漏和MyType的*



文章来源: How to release pointer from boost::shared_ptr?