Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::shared_ptr Exception Safety

I just realised reading this page that the constructor of std::shared_ptr with a single pointer argument is not noexcept.

Hence the following code contains a possible memory leak:

std::shared_ptr<int> p3 (new int); 

The reasonning is that two allocations could occure:

  • The first one before the call to the constructor
  • The second one in the constructor of shared_ptr (This is what happens in VS 2012 for example)

Two questions here:

Is it true that if the second allocation throws an exception, the memory of the first one leaks ?

If the answer is yes:

what is the correct idiom to use std::shared_ptr?

  • using make_shared
  • giving the ownership of the first allocation to a std::unique_ptr then transfering the ownership
  • Other thoughts ?
like image 759
Arnaud Avatar asked Nov 18 '13 17:11

Arnaud


People also ask

How do I write exception to safe code?

To write exception safe code, you must know first what level of exception safety each instruction you write is. For example, a new can throw an exception, but assigning a built-in (e.g. an int, or a pointer) won't fail. A swap will never fail (don't ever write a throwing swap), a std::list::push_back can throw...

What happens when shared_ptr goes out of scope?

The smart pointer has an internal counter which is decreased each time that a std::shared_ptr , pointing to the same resource, goes out of scope – this technique is called reference counting. When the last shared pointer is destroyed, the counter goes to zero, and the memory is deallocated.

Why is Make_unique exception safe?

The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter. Here indeterminately sequenced means that one is sequenced before another, but it is not specified which. Which means it is now exception safe.

Why is shared_ptr unique deprecated?

this function is deprecated as of C++17 because use_count is only an approximation in multi-threaded environment.


1 Answers

template<class Y> explicit shared_ptr(Y* p); 

[util.smartptr.shared.const]/6 Throws: bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.
[util.smartptr.shared.const]/7 Exception safety: If an exception is thrown, delete p is called.

So no, no memory leak.

like image 130
Igor Tandetnik Avatar answered Sep 22 '22 00:09

Igor Tandetnik