Efficient ways to initialize class members; both heap and stack allocated - c++

Assume we have the following:
//! SomeClass.hpp
class
{
public:
SomeClass( void );
~SomeClass( void )
{
delete mFoo;
delete mBar;
}
...
private:
Foo* mFoo;
Bar* mBar;
StackObj mStackFoo;
};
//! SomeClass.cpp
SomeClass::SomeClass( void )
{
mFoo = new Foo;
mBar = new Bar;
mStackFoo = StackObj( ... );
}
Now, when we initialize the pointers, my understanding is that the constructor will create unnecessary copies of SomeClass' members, thus allocating and then deallocating memory simply for the sake of allocating memory.
It's common to use initializer lists, coupled with a separate initialization function (for heap allocated memory) as a method to avoid this. Say SomeClass has a private member function defined as void initHeapMem( void ). Then we can do,
SomeClass::SomeClass( void )
: mFoo( NULL ),
mBar( NULL ),
mStackFoo( ... )
{
initHeapMem();
}
void SomeClass::initHeapMem( void )
{
mFoo = new Foo;
mBar = new Bar;
}
Naturally, this somewhat fixes the problem. The issue here I believe is that there's still the overhead of another function call being performed.
The reason why we can't use initialization lists for raw pointers is because they're not thread safe. If something goes wrong, and the program throws an exception, there will still be a memory leak. Note: this is according to what I've read, my apologies if this is wrong.
So, with boost/C++11, we can use smart pointers from an #include <tr1/memory> directive in the header file ( assuming we're using STL ).
If we were to use, say, std::unique_ptr< T >, then we'd have Bar* mBar and Foo* mFoo replaced with:
std::unique_ptr< Foo > mFoo;
std::unique_ptr< Bar > mBar;
Which would then allow us to do,
SomeClass::SomeClass( void )
mFoo( new Foo ),
mBar( new Bar ),
mStackFoo( ... )
{
}
Since the smart pointer effectively wraps the memory allocation in its own constructor.
While this is a nice solution, I personally am not one to use smart pointers for every heap object I create, and I know there are others in the C++ community who feel the same way.
tl;dr
With all of that out of the way, what I'm really wondering is if there are any more efficient alternatives to initializing class members within an object (especially with the advent of C++11), apart from the ones I listed above.

unique_ptr is the right solution here. It has several advantages:
It explicitly documents ownership. One of the issues with raw pointers is that they don’t indicate anything about who owns them. With unique_ptr you have a single owner, and must explicitly move ownership should you want to transfer it.
It has essentially no overhead; the only thing unique_ptr does is invoke the deleter, which you were going to do anyway. Now you have the performance benefits of deterministic memory behaviour without the effort of manual memory management.
It makes thread- and exception-safety much easier to attain, thanks to RAII. That means less fretting about instruction order, and less explicit cleanup code. You get the benefits of exceptions without all of the problems that caused them to be avoided in so much C++03 code.
shared_ptr is in my experience needed much less often than unique_ptr. Shared ownership is useful mainly when you have an immutable resource such as a texture or audio file, where loading and copying are both expensive, but which you want to unload when it’s not in use. shared_ptr also imposes the overhead of added safety (thread-safety in particular) and reference counting.
The disadvantage, of course, is that smart pointers impose a syntactic overhead. They are not as “native” as raw pointers. For that, you have typedef, auto, decltype, and rolling your own convenience functions such as make_unique.

Why can't you do this?
SomeClass::SomeClass( void ) :
mFoo(new Foo)
, mBar(new Bar)
{
}
They are raw pointers and no unnecessary copies are created.
I should also point out that the reason you use initializer lists is so that the object is in a valid state (that is, all members have valid values) when the constructor body is executed.
SomeClass::SomeClass( void )
{
//before this point, mFoo and mBar's values are unpredictable
mFoo = new Foo;
mBar = new Bar;
}
Regarding exceptions, the destructor of SomeClass will not be called ONLY if the exception is thrown inside the constructor itself.
Finally, regarding being thread safe or not, it depends on whether each thread has its own copy of SomeClass or not and whether SomeClass contains static members that are being written to.

Related

Verify at compile time that objects are created as shared_ptr

There are classes that I write (often as part of boost::asio) whose objects depend on being wrapped in a shared_ptr because they use shared_from_this(). Is there a way to prevent an object from being compiled if it's not instantiated in a shared_ptr?
So, what I'm looking for:
std::shared_ptr<MyClass> a = std::make_shared<MyClass>(); // should compile fine
std::unique_ptr<MyClass> a = std::make_unique<MyClass>(); // compile error
MyClass a; // compile error
Make its constructor private and give it a static factory member function that creates a shared_ptr. Don't forget to document your design decision in a comment!
// Thing that foos the bar
struct Foo : std::enable_shared_from_this<Foo>
{
// Returns a shared_ptr referring to a new instance of Foo
static std::shared_ptr<Foo> CreateShared()
{
return std::shared_ptr<Foo>(new Foo);
}
private:
// To avoid bugs due to the shared_from_this base,
// we restrict Foo creation to being via CreateShared().
Foo() = default;
};
(I can't imagine that std::make_shared would work due to the private ctor, but you can try it.)
I've got to say, though, this doesn't sound like the sort of thing a class should be taking responsibility for. It's kind of programming backwards.
To steal Eljay's words:
In general, it is best (if possible) that objects are not self-aware if they are contained in a shared_ptr, or on the heap, or on the stack, or by pointer, or in a vector, or as a data member, or as a global. As soon as they are self-aware of how they are life-cycle managed, they become a lot more constrained. Unnecessarily so. shared_from_this is (arguably) an anti-pattern. But... sometimes it may be a necessary anti-pattern.
I would prefer avoiding enable_shared_from_this and letting people use your Foo however they see fit, such as through a nice lean unique_ptr.

Is it mandatory to delete a pointer variable within a structure, before deleting the structure?

I have started to C++ and need some clarifications regarding memory management in C++. I have come across smart pointers, but I wish to understand some basic concepts.
Here's a sample structure
struct A
{
private:
int a;
void* b;
public:
A(int i, void* m) { a=i; b=m; }
};
main()
{
A * a1 = new A(10, 0);
//
//Some Code
if(on some condition) {
delete a1;
a1=nullptr;
}
}
When I delete a1, will m also be deleted automatically or should i explicitly delete m before deleting a1 as given below?
delete a1->b;
a1->b = nullptr;
delete a1;
a1=nullptr;
When I delete a1, will m also be deleted automatically
No, it won't (your code probably has a memory leak). You need an explicit destructor deleting it.
BTW, using a void*b; pointer field is poor taste. You should prefer some more explicit type (e.g. double*b; or SomeClass* b;) if you know it. This makes your code more readable, and give more opportunities for helpful type checking at compile time.
// inside struct A
~A() { delete b; };
Read about the rule of five.
Notice that struct-s are very similar to class-es in C++.
Avoid memory leaks. Tools like valgrind could be helpful. And using systematically smart pointers and standard containers should help to avoid them. If your field b was declared std::shared_ptr<std::string> b; the default destructor would have freed it appropriately. And perhaps you want it to be some std::vector<std::string> (again, the default destructor is releasing memory appropriately).
A good coding hint is to avoid, when possible, declaring raw pointers (prefer smart pointers and containers). When you have to declare one, you need to code its delete appropriately.
Welcome to C++, a very powerful language that requires you to take responsibility of the details to achieve the flexibility that allows such power. If you like, you can make it very complex, however for most constructs their is an easy way as well.
First of all, you ain't required to release memory, if your program exits, it will clean it. However, as you don't call delete, the Dtor will not be called which might cause specific code to not be executed.
So in general, it's good practice to clean up the allocated memory.
If you don't need the heap, don't use it
new A(10, 0) will allocate memory on the heap. If you don't want that, this can as well be created on the stack. Which causes auto cleanup: A a{10, nullptr};
Use RAII
As soon as you decide, you need heap allocated memory, you should default to std::unique_ptr. Which changes the code to: auto a = std::make_unique<A>(10, nullptr); With this, ownership is within the unique_ptr, which can be moved around (std::move). If you don't want to transfer ownership, you can dereference it or call the method get.
Applying these 2 practices, including for members, will prevent a lot of memory leaks and will reduce the time you need to think about it.
Don't use void*
void* is evil, don't use it unless you have to (and you only have to when interfacing with C). There are many ways of avoiding it. The best one is introducing an interface.
class I {
public:
virtual ~I() = default;
};
class M : public I
{
// ...
};
class A
{
// ...
std::unique_ptr<I> m;
// ...
};
Need something special?
Some times, you need something special in the Dtor, only in that case you should implement the Dtor explicitly. Given your question, I'm gonna assume you are a beginner and as such don't need to know about more details for now.

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.

shared_ptr based design issues

I use shared_ptr in my application design, and I have tendency that more and more objects become heap-allocated instead of to be a simple objects on stack (or agregates of more complex objects).
Instead of simple (but with risk that Foo::bar will become dangling reference in more complex situation) ...
struct Bar { };
struct Foo { Foo(Bar& bar) : bar(bar) { }; Bar& bar; };
int main() {
Bar bar;
Foo foo(bar);
// ...
}
... I need to do ...
struct Bar { };
struct Foo { Foo(shared_ptr bar) : bar(bar) { }; shared_ptr<Bar> bar; };
int main() {
shared_ptr<Bar> bar = make_shared<Bar>();
Foo foo(bar);
// ...
}
... because I want to avoid of manual objects life-time tracking
Did I missed point in shared_ptr usage or this is pay for automatic life-time management ? Or maybe this is bad design sign ?
It is a question of your object life cycle. You should use shared_ptr when you really share an object between multiple other objects.
In your case the owner of FOO and BAR must control the lifecycle of both. Maybe it is possible to make BAR a private member of you class FOO and let FOO control the life cycle.
I personally use the smart pointers to express the ownership of an object. Shared_ptr means that it is really shared and I am not the only owner of this object.
Scoped or unique pointer show that I am the only owner of the object. If you want to transfer the ownership you can use auto_ptr or the C++0x move semantics.
I have seen at least in bigger projects that the lack of life cycle control will lead to dangling objects. So you don't have a direct memory leak any longer because of automatic life-time management but you get circular dependencies. Which lead to the same result.
To answer your question if this is bad design. It depends on what you are doing.
It is a sign of bad design. shared_ptr exists for when your objects must be heap allocated. You should never additionally allocate anything on the heap just because you can use shared_ptr. The stack is still the best choice by miles.
You need to know before you start deciding how you're going to implement it, what objects need to go on the heap and which need to go on the stack, and what the ownership is. Then you can use shared_ptr as an implementation tool.
Have you tried working on values instead of pointers ?

What are potential dangers when using boost::shared_ptr?

What are some ways you can shoot yourself in the foot when using boost::shared_ptr? In other words, what pitfalls do I have to avoid when I use boost::shared_ptr?
Cyclic references: a shared_ptr<> to something that has a shared_ptr<> to the original object. You can use weak_ptr<> to break this cycle, of course.
I add the following as an example of what I am talking about in the comments.
class node : public enable_shared_from_this<node> {
public :
void set_parent(shared_ptr<node> parent) { parent_ = parent; }
void add_child(shared_ptr<node> child) {
children_.push_back(child);
child->set_parent(shared_from_this());
}
void frob() {
do_frob();
if (parent_) parent_->frob();
}
private :
void do_frob();
shared_ptr<node> parent_;
vector< shared_ptr<node> > children_;
};
In this example, you have a tree of nodes, each of which holds a pointer to its parent. The frob() member function, for whatever reason, ripples upwards through the tree. (This is not entirely outlandish; some GUI frameworks work this way).
The problem is that, if you lose reference to the topmost node, then the topmost node still holds strong references to its children, and all its children also hold a strong reference to their parents. This means that there are circular references keeping all the instances from cleaning themselves up, while there is no way of actually reaching the tree from the code, this memory leaks.
class node : public enable_shared_from_this<node> {
public :
void set_parent(shared_ptr<node> parent) { parent_ = parent; }
void add_child(shared_ptr<node> child) {
children_.push_back(child);
child->set_parent(shared_from_this());
}
void frob() {
do_frob();
shared_ptr<node> parent = parent_.lock(); // Note: parent_.lock()
if (parent) parent->frob();
}
private :
void do_frob();
weak_ptr<node> parent_; // Note: now a weak_ptr<>
vector< shared_ptr<node> > children_;
};
Here, the parent node has been replaced by a weak pointer. It no longer has a say in the lifetime of the node to which it refers. Thus, if the topmost node goes out of scope as in the previous example, then while it holds strong references to its children, its children don't hold strong references to their parents. Thus there are no strong references to the object, and it cleans itself up. In turn, this causes the children to lose their one strong reference, which causes them to clean up, and so on. In short, this wont leak. And just by strategically replacing a shared_ptr<> with a weak_ptr<>.
Note: The above applies equally to std::shared_ptr<> and std::weak_ptr<> as it does to boost::shared_ptr<> and boost::weak_ptr<>.
Creating multiple unrelated shared_ptr's to the same object:
#include <stdio.h>
#include "boost/shared_ptr.hpp"
class foo
{
public:
foo() { printf( "foo()\n"); }
~foo() { printf( "~foo()\n"); }
};
typedef boost::shared_ptr<foo> pFoo_t;
void doSomething( pFoo_t p)
{
printf( "doing something...\n");
}
void doSomethingElse( pFoo_t p)
{
printf( "doing something else...\n");
}
int main() {
foo* pFoo = new foo;
doSomething( pFoo_t( pFoo));
doSomethingElse( pFoo_t( pFoo));
return 0;
}
Constructing an anonymous temporary shared pointer, for instance inside the arguments to a function call:
f(shared_ptr<Foo>(new Foo()), g());
This is because it is permissible for the new Foo() to be executed, then g() called, and g() to throw an exception, without the shared_ptr ever being set up, so the shared_ptr does not have a chance to clean up the Foo object.
Be careful making two pointers to the same object.
boost::shared_ptr<Base> b( new Derived() );
{
boost::shared_ptr<Derived> d( b.get() );
} // d goes out of scope here, deletes pointer
b->doSomething(); // crashes
instead use this
boost::shared_ptr<Base> b( new Derived() );
{
boost::shared_ptr<Derived> d =
boost::dynamic_pointer_cast<Derived,Base>( b );
} // d goes out of scope here, refcount--
b->doSomething(); // no crash
Also, any classes holding shared_ptrs should define copy constructors and assignment operators.
Don't try to use shared_from_this() in the constructor--it won't work. Instead create a static method to create the class and have it return a shared_ptr.
I've passed references to shared_ptrs without trouble. Just make sure it's copied before it's saved (i.e., no references as class members).
Here are two things to avoid:
Calling the get() function to get the raw pointer and use it after the pointed-to object goes out of scope.
Passing a reference of or a raw pointer to a shared_ptr should be dangerous too, since it won't increment the internal count which helps keep the object alive.
We debug several weeks strange behavior.
The reason was:
we passed 'this' to some thread workers instead of 'shared_from_this'.
Not precisely a footgun, but certainly a source of frustration until you wrap your head around how to do it the C++0x way: most of the predicates you know and love from <functional> don't play nicely with shared_ptr. Happily, std::tr1::mem_fn works with objects, pointers and shared_ptrs, replacing std::mem_fun, but if you want to use std::negate, std::not1, std::plus or any of those old friends with shared_ptr, be prepared to get cozy with std::tr1::bind and probably argument placeholders as well. In practice this is actually a lot more generic, since now you basically end up using bind for every function object adaptor, but it does take some getting used to if you're already familiar with the STL's convenience functions.
This DDJ article touches on the subject, with lots of example code. I also blogged about it a few years ago when I first had to figure out how to do it.
Using shared_ptr for really small objects (like char short) could be an overhead if you have a lot of small objects on heap but they are not really "shared". boost::shared_ptr allocates 16 bytes for every new reference count it creates on g++ 4.4.3 and VS2008 with Boost 1.42. std::tr1::shared_ptr allocates 20 bytes. Now if you have a million distinct shared_ptr<char> that means 20 million bytes of your memory are gone in holding just count=1. Not to mention the indirection costs and memory fragmentation. Try with the following on your favorite platform.
void * operator new (size_t size) {
std::cout << "size = " << size << std::endl;
void *ptr = malloc(size);
if(!ptr) throw std::bad_alloc();
return ptr;
}
void operator delete (void *p) {
free(p);
}
Giving out a shared_ptr< T > to this inside a class definition is also dangerous.
Use enabled_shared_from_this instead.
See the following post here
You need to be careful when you use shared_ptr in multithread code. It's then relatively easy to become into a case when couple of shared_ptrs, pointing to the same memory, is used by different threads.
The popular widespread use of shared_ptr will almost inevitably cause unwanted and unseen memory occupation.
Cyclic references are a well known cause and some of them can be indirect and difficult to spot especially in complex code that is worked on by more than one programmer; a programmer may decide than one object needs a reference to another as a quick fix and doesn't have time to examine all the code to see if he is closing a cycle. This hazard is hugely underestimated.
Less well understood is the problem of unreleased references. If an object is shared out to many shared_ptrs then it will not be destroyed until every one of them is zeroed or goes out of scope. It is very easy to overlook one of these references and end up with objects lurking unseen in memory that you thought you had finished with.
Although strictly speaking these are not memory leaks (it will all be released before the program exits) they are just as harmful and harder to detect.
These problems are the consequences of expedient false declarations: 1. Declaring what you really want to be single ownership as shared_ptr. scoped_ptr would be correct but then any other reference to that object will have to be a raw pointer, which could be left dangling. 2. Declaring what you really want to be a passive observing reference as shared_ptr. weak_ptr would be correct but then you have the hassle of converting it to share_ptr every time you want to use it.
I suspect that your project is a fine example of the kind of trouble that this practice can get you into.
If you have a memory intensive application you really need single ownership so that your design can explicitly control object lifetimes.
With single ownership opObject=NULL; will definitely delete the object and it will do it now.
With shared ownership spObject=NULL; ........who knows?......
If you have a registry of the shared objects (a list of all active instances, for example), the objects will never be freed. Solution: as in the case of circular dependency structures (see Kaz Dragon's answer), use weak_ptr as appropriate.
Smart pointers are not for everything, and raw pointers cannot be eliminated
Probably the worst danger is that since shared_ptr is a useful tool, people will start to put it every where. Since plain pointers can be misused, the same people will hunt raw pointers and try to replace them with strings, containers or smart pointers even when it makes no sense. Legitimate uses of raw pointers will become suspect. There will be a pointer police.
This is not only probably the worst danger, it may be the only serious danger. All the worst abuses of shared_ptr will be the direct consequence of the idea that smart pointers are superior to raw pointer (whatever that means), and that putting smart pointers everywhere will make C++ programming "safer".
Of course the mere fact that a smart pointer needs to be converted to a raw pointer to be used refutes this claim of the smart pointer cult, but the fact that the raw pointer access is "implicit" in operator*, operator-> (or explicit in get()), but not implicit in an implicit conversion, is enough to give the impression that this is not really a conversion, and that the raw pointer produced by this non-conversion is an harmless temporary.
C++ cannot be made a "safe language", and no useful subset of C++ is "safe"
Of course the pursuit of a safe subset ("safe" in the strict sense of "memory safe", as LISP, Haskell, Java...) of C++ is doomed to be endless and unsatisfying, as the safe subset of C++ is tiny and almost useless, as unsafe primitives are the rule rather than the exception. Strict memory safety in C++ would mean no pointers and only references with automatic storage class. But in a language where the programmer is trusted by definition, some people will insist on using some (in principle) idiot-proof "smart pointer", even where there is no other advantage over raw pointers that one specific way to screw the program state is avoided.