No-op deallocator for boost::shared_ptr - c++

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

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.

Enforce no bald pointers in C++

Generally speaking, in this crazy modern world full of smart pointers, I'm coming round to the fact that bald/bare pointers shouldn't be in method signatures.
I suppose there might be some cases where you need bald pointers for performance reasons but certainly I've always managed with references or references to smart pointers.
My question is this, can anyone suggest an automated way to enforce this? I can't see a way with clang, GCC or vera++
I think it is ok for non-owning raw-pointers to be used in method signatures. It is not ok to use "owning" raw-pointers.
For example this is quite ok:
void bar(const Widget* widget) {
if (widget)
widget->doSomething();
}
void foo() {
Widget w;
bar(&w);
}
If you want the Widget to be nullable you can't use a reference and using a smart pointer would be slower and not express the ownership model. The Widget can be guaranteed to be alive for the whole scope of foo. bar simply wants to "observe" it so a smart pointer is not needed. Another example where a non-owning raw-pointer is appropriate is something like:
class Node {
private:
std::vector<std::unique_ptr<Node>> children_; // Unique ownership of children
Node* parent_;
public:
// ...
};
The Node "owns" its children and when a Node dies its children die with it. Providing encapsulation of Node hasn't been broken, a Node can guarantee its parent is alive (if it has one). So a non-owning raw-pointer is appropriate for a back reference to the parent. Using smart pointers where they are not required makes code harder to reason about, can result in memory leaks and is premature pessimization.
If smart pointers are used throughout instead, all kinds of things can go wrong:
// Bad!
class Node {
private:
std::vector<std::shared_ptr<Node>> children_; // Can't have unique ownership anymore
std::shared_ptr<Node> parent_; // Cyclic reference!
public:
// Allow someone to take ownership of a child from its parent.
std::shared_ptr<Node> getChild(size_t i) { return children_.at(i); }
// ...
};
Some of these problems can be solved by using weak_ptr instead of shared_ptr but they still need to be used with care. A weak_ptr is a pointer that has the option of owning.
The point is to use the appropriate kind of pointer in the appropriate context and to have an ownership model that is as simple as possible.
And no, I don't think there is an automated way of enforcing this, it is part of the design. There are tricks you can use like Cheersandhth.-Alf said to try and enforce a particular class is used in the way you want by restricting access.
I don't know of any automated tool to do this, but such a check wouldn't be too hard to implement in cppcheck, which is open source and AIUI offers an easy way to add new rules.
I don't think it's a good idea to completely stay away from raw (bald, bare) pointers even for function arguments. But it can sometimes be a good idea to make sure that all instances of a certain type are dynamic and owned by smart pointers. This involves two measures:
Ensure (to the degree practical) that the type can only be instantiated dynamically.
Ensure (to the degree practical) that instantiation yields a smart pointer.
The first point is easy: just make the destructor non-public, and voilá, the few remaining ways to instantiate that type non-dynamically are not very natural. Any simple attempt to declare a local or namespace scope variable will fail. As will simple attempts to use that type directly as a data member type:
#include <memory>
template< class Type >
void destroy( Type* p ) { delete p; }
class Dynamic
{
template< class Type > friend void destroy( Type* );
protected:
virtual ~Dynamic() {}
};
//Dynamic x; //! Nope.
struct Blah
{
Dynamic x; //! Nope, sort of.
};
auto main()
-> int
{
//Dynamic x; //! Nope.
new Blah; //!Can't delete, but new is OK with MSVC 12...
}
Visual C++ 12.0 unfortunately accepts the above code as long as the out-commented statements remain out-commented. But it does issue a stern warning about its inability to generate a destructor.
So, Dynamic can only be created dynamically (without using low-level shenanigans, or ignoring that MSVC warning and accepting a memory leak), but how to ensure that every new instance is owned by a smart pointer?
Well you can restrict access to the constructors so that a factory function must be used. Another way to ensure use of the factory function is to define a placement allocation function, operator new, that an ordinary new-expression can't access. Since that's most esoteric and possibly non-trivial, and not of clear-cut value, the below code just restricts access to the constructors:
#include <memory> // std::shared_ptr
#include <utility> // std::forward
// A common "static" lifetime manager class that's easy to be-"friend".
struct Object
{
template< class Type >
static
void destroy( Type* p ) { delete p; }
template< class Type, class... Args>
static
auto create_shared( Args&&... args )
-> std::shared_ptr<Type>
{
return std::shared_ptr<Type>(
new Type( std::forward<Args>( args )... ),
&destroy<Type>
);
}
};
class Smart
{
friend class Object;
protected:
virtual ~Smart() {}
Smart( int ) {}
};
//Smart x; //! Nope.
struct Blah
{
//Smart x; //! Nope, sort of.
};
auto main()
-> int
{
//Smart x; //! Nope.
//new Blah; //!Can't delete.
//new Smart( 42 ); // Can't new.
Object::create_shared<Smart>( 42 ); // OK, std::shared_ptr
}
One problem with this approach is that the standard library's make_shared doesn't support a custom deleter, and shared_ptr doesn't use the common deleter of unique_ptr. One may hope that perhaps this will be rectified in future standard.
Disclaimer: I just wrote this for this answer, it's not been extensively tested. But I did this in old times with C++98, then with a macro for the create-functionality. So the principle is known to be sound.
The problem with this idea is that in the smart pointer world, T* is just a shorthand for optional<T&>. It no longer implies memory management, and as a result it becomes a safe idiom to identify an optional non-owned parameter.

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

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.

boost::shared_ptr drop-in replacement

Recently i started to work on one legacy project and trying to fix segfaults (double delete). Many of them is happening on boost::shared_ptr destructor or operator=(on objects that contain a shared_ptr). The code contains is massive usage of shared_ptr-s, including copying, reset()-ing, assigning etc. According to boost docs we have not valid usage - its not safe to destruct/copy/reset same shared_ptr in many threads.
Locking each time seems impossible, so im searching for drop-in replacement for boost::shared_ptr. So the question is: if i replace all boost::shared_ptr with std::shared_ptr or std::tr1::shared_ptr will the solve this issue? Seems tr1 is safer version but its not clear for me. Second question - is c++0x version any better than tr1 ? (note we have gcc 4.4.6 and cannot upgrade it)
Accoring to gcc docs, c++11 std::shared_ptr should fix that, but im not sure about gcc4.4 version...
UPD: Just maked experiment and now i know all 3 implementations do segfault on this code(gcc 4.4).. seems i should make custom class or maybe other workaround...
#include <iostream>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<int> ptrtype;
ptrtype p(new int);
void test() {
for(long i=0; i<1000000; ++i) {
ptrtype p1 = p;
p = ptrtype();
p.reset( new int );
}
}
int main() {
boost::thread_group tg;
for(int i=0; i<100; ++i) tg.add_thread( new boost::thread(test) );
tg.join_all();
std::cout << "Normal exit\n";
return 0;
}
Step 1: Build a class like this, and replace usage of boost::shared_ptr<T> with it.
template<typename T>
struct trivial_ptr {
T* t;
template<typename U>
void reset( U* p ) {t=p;}
void reset( T* p = NULL ) { t=p; }
template<typename U>
trivial_ptr<T>& operator=(trivial_shared_ptr<U>const& o) {
t = o.t;
return *t;
}
explicit trivial_ptr( T* p ):t(p) {}
...
};
this class is not intended to run, but just to compile with the correct interface. Once you have compiled, you can ensure you know what parts of the boost::shared_ptr interface you are using. (Are you using custom deleters? etc -- the problem could be harder, or easier, and the above can help test it)
Once you are there, you can work out how hard it will be to write up a shared_ptr<T> that handles multiple threads accessing the same variable at the same time.
Now, this is extremely messy. If one thread resets a given shared_ptr while another thread reads from it, the pointer read from may be completely invalid by the time the reading thread has access to it. In effect, you need to guard all access to the underlying pointer in a mutex, which is utterly impractical.
On the other hand, if what you have is multiple readers, and never a reader and a writer, you are in better shape -- in theory, you could fix the problem with the use of appropriate locks on the reference count code.
However, what you actually describe seems to involve multiple threads both reading and writing to the same variable. And that is fundamentally broken in a way that mere thread safety on the shared_ptr variable is not going to fix.
The problem you appear to have is attempting to modify the same instance of a variable in two separate threads (AKA a data race). shared_ptr is no more protected against this than int's are. Your reference to the gcc docs says the same thing ("same level of thread safety as built-in types"). Attempting to modify the same instance of a shared_ptr in two different threads requires some sort of synchronization to prevent the data race. Attempting to modify two different instances of a shared_ptr that are pointing to the same object is OK (no data race, or shared_ptr must implement whatever is necessary to prevent a data race internally). Attempting to modify the object that they point to is also a data race.
std::shared_ptr may use atomic ints if the compiler/architecture/implementation supports/use it. But i wouldn't bet on it, and doing so will make your code less portable. But it may work as a temporary workaround (e.g. to have a running program so you understand what the code is supposed to do).
Writing your own shared_ptr wrapper might be an option, but your code will still need to be audited for deadlocks.

Socket pointer transfer of ownership with tcp::acceptor::async_accept

I've recently started using Boost.Asio in a project and would like to know whether anyone knows a clean solution to transfer ownership of a newly created socket to tcp::acceptor::async_accept, which would in turn transfer this ownership to the accept handler function.
This isn't an incoherent desire, mind you, since the handler is to be called exactly once.
I have noticed I can't std::bind() an std::unique_ptr<> as parameter, since std::bind() requires its parameters to be CopyConstructible, and rightfully so. Not only that, but Boost's AcceptHandler concept is also required to be CopyConstructible.
So my options would be:
Go the deprecated std::auto_ptr<> way of moving objects with the copy constructor, potentially causing obscure bugs on new releases of Boost.Asio.
Use std::shared_ptr<> and have no way to take the shared ownership off the pointer once it's not needed anymore, i.e. when it reaches the actual handler function (this is how the job is done on the examples at http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/examples.html as far as I've read).
or
You have a better idea for me.
I'm pretty much at a loss here. Can anyone enlighten me?
I tried to find a way to do this using the c++0x standard library, but could not.
Eventually I settled on writing my own rvalue_reference_wrapper and rvalue_ref() convenience class. As per usual with std::bind, you need to wrap your non copyable object in something that is copyable (reference_wrapper is the best example). You could also have just passed a pointer, but that means changing your interface.
This worked on my machine:
#include <iostream>
#include <functional>
#include <memory>
template< class T >
struct rvalue_reference_wrapper
{
rvalue_reference_wrapper( T&& t )
: t_(std::move(t))
{}
operator T&&() const volatile
{
return std::move(t_);
}
private:
T&& t_;
};
template< class T >
rvalue_reference_wrapper<T> rvalue_ref( T&& t )
{
return rvalue_reference_wrapper<T>(std::move(t));
}
void go( std::unique_ptr<int> i )
{
std::cout << *i << std::endl;
}
int main()
{
std::unique_ptr<int> i(new int(1));
auto b = std::bind( go, rvalue_ref(std::move(i)) );
//auto b = std::bind( go, std::ref(std::move(i)) ); // Wont work
b();
}
I have not made the code bulletproof, but welcome some discussion about the need for an rvalue_reference_wrapper, or how to simulate one using std::reference_wrapper.
Also, for your specific case, you will likely need to write a difference version of rvalue_reference_wrapper, which holds the object by value not by rvalue reference, since your original unique_ptr is likely going to leave scope (and be destroyed) since you are using async asio calls.