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

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

我可以看到文档中不存在发布函数,在常见问题中解释了为什么它不提供发布函数,就像发布不能在不唯一的指针上发布一样。 我的指针是独一无二的。 我怎样才能释放我的指针? 或者哪个提高智能指针类使用,将允许我释放指针? 我希望你不会说使用auto_ptr 🙂

您需要使用删除程序,您可以请求不删除基础指针。

看到这个答案 (已被标记为这个问题的重复)以获取更多信息。

别。 Boost的FAQ条目:

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

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

此外,由release()返回的指针将很难可靠地释放,因为可以使用定制的删除器创build源shared_ptr。

所以,如果唯一的shared_ptr实例指向你的对象(当unique()返回true),并且对象不需要特殊的删除器,这将是安全的。 如果你使用了.release()函数,我仍然会质疑你的devise。

你可以使用假删除器。 那么实际上指针不会被删除。

 struct NullDeleter {template<typename T> void operator()(T*) {} }; // pp of type some_t defined somewhere boost::shared_ptr<some_t> x(pp, NullDeleter() ); 

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

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

现在有没有办法检查ref count的所有者总数是否大于1?

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

但是,这将删除指针指向对象的最后一个引用时指向的对象。 然而,这首先是智能指针所期望的行为。

如果你只是想要一个不包含对象的引用,你可以创build一个boost::weak_ptr (见boost文档 )。 weak_ptr保存对该对象的引用,但不会添加到引用计数中,因此当只有弱引用存在时,该对象将被删除。

分享的基础是信任。 如果程序中的某个实例需要释放原始指针,几乎肯定shared_ptr是错误的types。

但是,最近我也想这样做,因为我需要从不同的进程中释放堆。 最后,我被告知,我以前的决定使用一些std::shared_ptr没有被认为是。

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

原谅他们,因为他们不知道他们做什么。 这个例子适用于boost :: 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; } 

你可以删除共享指针,这对我来说似乎很相似。 如果指针总是唯一的,那么std::auto_ptr<>是个不错的select。 请记住,STL容器中不能使用唯一的指针,因为它们的操作会执行大量的复制和临时重复。

这是一个可能工作的黑客。 我不会推荐它,除非你在真正的约束。

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

如果你的指针确实是唯一的,如果前者不适用于你的编译器,则使用std::unique_ptrboost::scoped_ptr 。 否则考虑将boost::shared_ptrboost::weak_ptr结合使用。 查看详细的Boost文档 。

我正在使用Poco :: HTTPRequestHandlerFactory,期望返回一个原始的HTTPRequestHandler *,一旦请求完成,Poco框架删除处理程序。

同样使用DI Sauce项目来创build控制器,但是Injector返回了我不能直接返回的shared_ptr,并且返回handler.get()也不行,因为只要这个函数返回了shared_ptr就离开了scope并删除了handler在执行之前,所以这是一个合理的(我认为)有一个.release()方法的理由。 我最终创build了一个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); } 

既满足酱油又适合波科,效果很好。

我需要通过asynchronous处理程序传递一个指针,并在失败的情况下保持自毁行为,但最终的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

我不完全确定你的问题是关于如何实现这一点,但如果你想从一个shared_ptr行为,其中,如果你从一个shared_ptr释放值,所有其他共享指针为相同的值成为nullptr,那么你可以把一个unique_ptr放在一个shared_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 

此行为允许您共享资源(如数组),然后再使用该资源,同时使对该资源的所有共享引用无效。

简单的解决scheme,增加参考,然后泄漏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的内存泄漏*