Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use the C++ Boost shared_ptr to program as if I was coding in Java, as in, not care about memory management?

It's been a while I coded in C/C++, and now I need its efficiency for a project I'm doing.

What I understand from this shared_ptr is that it basically deletes the object when I need it to. So, if, for example, my object has a vector of shared_ptr, I wouldn't have to worry about iterating through the vector and deleting each element in the destructor? In other words, I don't have to worry about memory management as long as I use these? Or am I totally misunderstanding this? It sounds too good to be true.

like image 550
zxcvbnm Avatar asked Jan 17 '10 16:01

zxcvbnm


2 Answers

You have to understand that shared pointers are implemented using a reference count, that means that if you have cycles in your pointer graph then the objects will not be released. That is, if a points to b and b points to a but nothing points to a or b, then neither a nor b will be released because they both have a reference count of '1'.

Boost provides weak pointers to get around this, which allows you to store a pointer to a shared object without incrementing its reference count. Weak pointers provide a layer of safety in that attempting to dereference the pointer after the shared pointer has been released will raise an exception rather than crashing the program.

Shared pointers are also quite expensive (at least compared to a raw pointer) in performance terms - but it's better to use them and then remove them once a profiler identifies a bottleneck rather than not use them everywhere.

Other than that, yes, they are very useful for managing dynamically allocated objects.

Edit: Another gotcha (that's mentioned on the boost pages) is to avoid "temporary" shared_pointers:

func(A(), boost::shared_ptr<B>(new B));

because the compiler is allowed to optimise this as

tmp1 = new B;
tmp2 = A();
tmp3 = boost::shared_ptr<B>(tmp1)
func(tmp2,tmp3)

which might look OK on first glance, but if A() happens to throw an exception then B has been allocated, but the shared_ptr hasn't gotten a hold of it yet, so the pointer never gets released.

like image 115
Adam Bowen Avatar answered Sep 25 '22 06:09

Adam Bowen


You can do this but it's generally a bad idea. For a start you may lose some or all of the efficiency that you think you might be gaining.

More importantly, it sounds like you are trying to avoid designing your code. Java has gc, so you don't have to worry about memory management but you should still be concerned about object lifetimes. If you are not clear about who owns what you are likely to end up with a muddled design.

C++ gives you a lot of options when it comes to object lifetimes, not every complex object needs to be allocated on the heap. shared_ptr should be used for objects that require shared ownership (as it's name implies) but this should be a positive design decision. There are better ways to own an object if shared or transferable ownership aren't required.

like image 30
CB Bailey Avatar answered Sep 24 '22 06:09

CB Bailey