How do you make std::shared_ptr not call delete() - c++

I have functions that take in std::shared_ptr as an argument so I am forced to use std::shared_ptr, but the object I am passing to the function is not dynamically allocated. How do I wrap the object in std::shared_ptr and have std::shared_ptr not call delete on it.

MyType t;
nasty_function(std::shared_ptr<MyType>(&t, [](MyType*){}));

Specify a no-op deleter when creating the shared pointer. E.g. like this:
void null_deleter(MyType *) {}
int main()
{
MyType t;
nasty_function(std::shared_ptr<MyType>(&t, &null_deleter));
}

The best way to do this is to use the aliasing constructor:
nasty_function(std::shared_ptr<MyType>(std::shared_ptr<MyType>{}, &t));
Compared to the null deleter approach, this doesn't need to allocate a control block, and is noexcept.
As noted by #Casey and #Nevin, this should only be done when you are sure that the function won't attempt to take shared ownership, or if the object would outlive everything that might "own" it.

Boost.Core provides a null_deleter function object exactly for this purpose.
Citing the documentation:
The header <boost/core/null_deleter.hpp> defines the boost::null_deleter function object, which can be used as a deleter with smart pointers such as unique_ptr or shared_ptr. The deleter doesn't do anything with the pointer provided upon deallocation, which makes it useful when the pointed object is deallocated elsewhere.
Example from the documentation:
std::shared_ptr< std::ostream > make_stream()
{
return std::shared_ptr< std::ostream >(&std::cout, boost::null_deleter());
}

You can do this trick:
A a;
shared_ptr<A> pa(&a);
foo(pa);
new (&pa) shared_ptr<A>(); // pa "forgets" about a

i was just searching for a solution, saw this question. found nothing and made a great one this is my code
class HBitmap : public shared_ptr<HBITMAP__>
{
public:
HBitmap();
HBitmap(HBITMAP Handle);
bool autoDelete = true;
};
Win32::HBitmap::HBitmap(HBITMAP Handle)
: shared_ptr<HBITMAP__>(Handle, [&](HBITMAP hBitmap) {if(autoDelete)DeleteObject(hBitmap);})
{
}
this solution is a combination of lambda expressions and inheritance.
very well formed. fast. you can't expect anything more. not only you can set the deleter, but if you do some modifications, you can use a std::function<void(pointer)> as a custom deleter. with lambdas you can run free and do what ever you want.

Related

is C++ raw pointer used to initialise a shared pointer invalidated when the shared pointer goes out of scope? [duplicate]

I have functions that take in std::shared_ptr as an argument so I am forced to use std::shared_ptr, but the object I am passing to the function is not dynamically allocated. How do I wrap the object in std::shared_ptr and have std::shared_ptr not call delete on it.
MyType t;
nasty_function(std::shared_ptr<MyType>(&t, [](MyType*){}));
Specify a no-op deleter when creating the shared pointer. E.g. like this:
void null_deleter(MyType *) {}
int main()
{
MyType t;
nasty_function(std::shared_ptr<MyType>(&t, &null_deleter));
}
The best way to do this is to use the aliasing constructor:
nasty_function(std::shared_ptr<MyType>(std::shared_ptr<MyType>{}, &t));
Compared to the null deleter approach, this doesn't need to allocate a control block, and is noexcept.
As noted by #Casey and #Nevin, this should only be done when you are sure that the function won't attempt to take shared ownership, or if the object would outlive everything that might "own" it.
Boost.Core provides a null_deleter function object exactly for this purpose.
Citing the documentation:
The header <boost/core/null_deleter.hpp> defines the boost::null_deleter function object, which can be used as a deleter with smart pointers such as unique_ptr or shared_ptr. The deleter doesn't do anything with the pointer provided upon deallocation, which makes it useful when the pointed object is deallocated elsewhere.
Example from the documentation:
std::shared_ptr< std::ostream > make_stream()
{
return std::shared_ptr< std::ostream >(&std::cout, boost::null_deleter());
}
You can do this trick:
A a;
shared_ptr<A> pa(&a);
foo(pa);
new (&pa) shared_ptr<A>(); // pa "forgets" about a
i was just searching for a solution, saw this question. found nothing and made a great one this is my code
class HBitmap : public shared_ptr<HBITMAP__>
{
public:
HBitmap();
HBitmap(HBITMAP Handle);
bool autoDelete = true;
};
Win32::HBitmap::HBitmap(HBITMAP Handle)
: shared_ptr<HBITMAP__>(Handle, [&](HBITMAP hBitmap) {if(autoDelete)DeleteObject(hBitmap);})
{
}
this solution is a combination of lambda expressions and inheritance.
very well formed. fast. you can't expect anything more. not only you can set the deleter, but if you do some modifications, you can use a std::function<void(pointer)> as a custom deleter. with lambdas you can run free and do what ever you want.

How to use a shared_ptr with a pointer to struct that should not be freed

Currently I'm using some functions from the glib library. With glib also comes the gio. glib is a C library and therefore I need to delete some structures that I create.
for many of the objects I create a smartpointer eg:
std::shared_ptr<GAsyncQueue> my_queue = std::shared_ptr<GAsyncQueue>(g_async_queue_create(), g_async_queue_unref);
For this creates a shared pointer to an GAsyncQueue and this is safely destroys the queue on its end of its life.
However, I encounter a problem when I obtain a pointer from the gio library that I should not free. In the following code my_connection is a GSocketClient which implements (in glib speak) GIOStream.
std::shared_ptr<GInputStream> my_input_stream =
std::shared_ptr<GInputStream> (
g_io_stream_get_input_stream(G_IO_STREAM(my_connection.get()))
);
Because the documentation on GIOStream mentions, that the pointer obtained with g_io_stream_get_input_stream() should not be freed. That is because it is owned by the my_connection instance.
I thought about creating a lamda for the destroy object, the second parameter of a shared pointer object. eg auto deleter = [](GInputStream* ptr) {}; and then give that lambda as destroy function to the shared pointer, but that feels a kind of stupid.
Well, alternative to no-op deleter might be using aliasing shared pointer
template <class U> shared_ptr (const shared_ptr<U>& x, element_type* p) noexcept;
It shares x, but after get() you'll get back p.
Discussion: What is shared_ptr's aliasing constructor for?
You probably just don't need a std::shared_ptr. And you probably don't even need a pointer.
As I read your question and comments, I don't see any point against
auto& my_input_stream = *( g_io_stream_get_input_stream(G_IO_STREAM(my_connection.get())) )
It is true that pointers allow optional data. However, it's also true that it's mostly used the wrong way. Having
void foo( type* ptr)
{
if (!ptr)
throw exception;
}
often doesn't make sense. If the function has to to work on concrete data, allowing a NULL parameter is only useful if you then worry about providing that data. Otherwise, just require a reference (possibly const) to the object.
Smart pointers are useful; but they're still pointers. Avoiding them altogether, if possible, is even better.
From the comments:
However, a reference must always be initialized
Absolutely. Since C++11 though we've got std::reference_wrapper which can also be reassinged and stored in containers.
You can use a deleter type that does nothing, but it will need to be passed as an argument to the shared_ptr's constructor
struct DoNothing {
template <typename T>
void operator()(T*) const noexcept { }
};
When creating a shared_ptr you will need to create one of these deleters and pass it in the constructor (as you're doing with the lambda). You can make this easier on yourself with an intermediate function
template <typename T>
std::shared_ptr<T> non_deleting_shared_ptr(T* ptr) {
return {ptr, DoNothing};
}
auto my_input_stream =
non_deleting_shared_ptr(
g_io_stream_get_input_stream(G_IO_STREAM(my_connection.get()));
However the bigger question is why you're using smart pointers when you don't want ownership to be a part of it. You'd almost certainly be better off with just a GAsyncQueue*, unless of course you're in a situation where you have a shared_ptr that needs to free sometimes. Like a data member maybe?

Smart pointer that does transfer of ownership and is not shared when C++11 is not an option

Currently I am solving my problem with boost::shared_ptr but the semantics is not quite right, since I am "transplanting" members from one object to another. I was looking through this list but it didn't yield too much. Same goes for my brief google searches.
Essentially I am looking for a unique_ptr implementation that works with my gcc4.2 (Hence the restriction to not use C++11)
You could stick with std::auto_ptr until Boost implements unique_ptr on top of the new Boost Move library (C++03 compatible).
See this mailing list traffic d.d. November 10th 2011: http://boost.2283326.n4.nabble.com/smart-ptr-Inclusion-of-unique-ptr-td4021667.html
Edit And Boost Interprocess has a uniqe_ptr<> class template floating around:
http://www.boost.org/doc/libs/1_48_0/doc/html/boost/interprocess/unique_ptr.html
Depending on what exactly you want, you might consider using boost::scoped_ptr. It is very similar to std::unique_ptr, but it cannot be moved (because C++03 doesn't know about move-semantics). It can, however be swapped. So, when you want to transfer ownership, just do this:
boost::scoped_ptr<T> dummy;
dummy.swap(my_ptr);
// now you have basically transferred ownership from my_ptr to dummy
Use std::auto_ptr<..>, it has exactly what you need.
llvm::OwningPtr - it has take method to take ownership.
boost::shared_ptr with custom deleter.
This is something I used in unit test to simulate Corba _var class behaviour.
struct CondDel {
bool doDel;
CondDel() : doDel(true) {
}
template<typename T>
void operator()(T* p) {
if (doDel)
delete p;
}
};
class MyCorbaObj_var : public boost::shared_ptr<_objref_MyCorbaObj> {
public:
MyCorbaObj_var(_objref_MyCorbaObj* p) : boost::shared_ptr<_objref_MyCorbaObj>(p, CondDel()) {
}
_objref_MyCorbaObj* _retn() {
CondDel* cd = (CondDel*)_internal_get_deleter(typeid(CondDel));
cd->doDel = false;
return get();
}
};
If you want copying objects of your class to make new copies of the pointed-to items, then no kind of pointer (auto_ptr, shared_ptr or naked pointer) will do what you want without some extra work on your part. You will need to manage the copying yourself. Be sure you implement a copy constructor and assignment operator so that they clone the pointed-to items and store the new pointers in the destination object. If you do this, auto_ptr and shared_ptr will both work just fine for you.

No-op deallocator for boost::shared_ptr

Is there a stock no-op deallocator in Boost to use with boost::shared_ptr for static objects, etc.
I know it's ultra-trivial to write, but I don't want to sprinkle my code with extra tiny functions if there is already one available.
Yes there is one here:
#include <boost/serialization/shared_ptr.hpp> // for null_deleter
class Foo
{
int x;
};
Foo foo;
boost::shared_ptr< Foo > sharedfoo( &foo, boost::serialization::null_deleter() );
There is, of course, a danger with the fact that you need to know the function you call doesn't store the shared_ptr for later use, as it actually goes against the policy of shared_ptr in that the underlying object remains valid until that of the last instance of the shared_ptr.
Solution uses Boost.Lambda:
#include <boost/shared_ptr.hpp>
#include <boost/lambda/lambda.hpp>
int main()
{
int *p = new int(5);
{
boost::shared_ptr<int> sp(p, boost::lambda::_1);
}
delete p;
}
'boost::lambda::_1' creates an empty functor that takes one argument.
You'll probably want to put a //comment in there to let people know why you did it, though.
If Boost <= 1.54, use boost/log/utility/empty_deleter.hpp.
If Boost == 1.55, use boost/utility/empty_deleter.hpp.
If Boost >= 1.56, use boost/core/null_deleter.hpp.
Wouldn't it be cleaner just to take an extra reference so the deallocator is never called? (Although that's still not very clean.)
I can't say that there's no function in Boost which would do the job, but it doesn't sound like something they would want to include.
EDIT: Having read the comments and a little documentation, it boils down to this:
Reference leaking. At some point, execute this:
new shared_ptr( my_global_shared_ptr );
Advantages: conceptually easy. Disadvantages: you are leaking something on the heap.
Custom deallocator. Since shared_ptr requires little of the deallocator function, an anonymous identity function like that provided in the other answer would do fine.
Advantages: leverages Boost and has absolutely no overhead. Disdvantages: requires a little documentation.
Non-static global object. If there is a global shared_ptr for your object, that should be the only means of access to it. Replace the declaration of the global with a shared_ptr intialized by new my_class. I think this is best.
There's a ticket for this on the Boost bug tracker: https://svn.boost.org/trac/boost/ticket/1913 - no activity for a long time until some murmur two weeks ago.
FWIW, this what I'm using.
I use it in unit tests to adapt a local into a shared_ptr.
// The class NoOp_sptr_Deleter can be used to construct a shared_ptr<>()
// that will NOT delete the pointee.
// This can be helpful in unit-testing. Wrapping a local as a shared_ptr.
// Do take care with the lifetimes though.
struct NoOp_sptr_Deleter
{
void operator()(void const *) const {}
};
template<typename T>
boost::shared_ptr<T> FakeSharedPtrFromRef(T& aRef)
{
return boost::shared_ptr<T>(&aRef, NoOp_sptr_Deleter() );
}

Is there a boost smart pointer class that can be configured not to delete at destruction?

I have a list of smart pointers. I want some of these smart pointers to act as regular pointers, meaning they are simply a reference to an instance and are not involved in its deallocation. They might for example point to instances allocated on the stack. The other smart pointers in the list should act as regular boost::shared_ptr.
Here is how the class might look:
template<class T> smart_ptr {
private:
T *p;
boost::shared_ptr<T> sp;
public:
smart_ptr(T *p): p(p), shared(0) { } // p will not be deleted
smart_ptr(boost::shared_ptr<T> &sp): p(sp.get()), sp(sp) { }
T *get() const { return p; }
}
If there is a boost class that does this, I would prefer to use it instead of writing a class myself. It appears there are none, or am I mistaken?
One constructor for shared_ptr takes the destructor method, and you can pass in an empty functor.
Using Custom Deallocator in boost::shared_ptr
(You want just an empty function.)
I've got this little class in my toolbox for this:
struct nodelete {
template <typename T>
void operator()( T * ) {}
};
Usage:
int main() {
SomeClass sc;
boost::shared_ptr<SomeClass> p( &sc, nodelete() );
// ...
}
This sounds like a boost::weak_ptr:
http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/weak_ptr.htm
But you can only create a weak_ptr from a shared_ptr, so as for your stack-allocated objects, I'm not sure how that would work.
This smells of bad design.
I can't think of a reasonable situation where you wouldn't want to delete the pointer. Here are the (unreasonable IMO) situations:
1) static duration objects. Instead, consider using a singleton mixin (use CRTP to mixin the singleton that has an instance() method that returns a copy of a local static shared_ptr<>; local statics are thread unsafe so you'll also need an appropriate static mutex if this could be called by multiple threads). The benefit of using a proper singleton is that your singleton will be destructed at exit after other objects that continue to hold shared_ptr<>'s to it.
2) objects created on the stack. Just don't do this. Instead create the object on the heap protected by a shared_ptr<>. If you need to create shared_ptr<>'s to the object in different parts of the code (i.e. you can't take copies from an original shared_ptr<>) then inherit from boost::enable_shared_from_this<> and get shared_ptr<>'s from shared_from_this().
Is there some other reason you want a shared_ptr<> that doesn't ever delete anything?