Boost’s make_shared() function promises to be exception-safe while attempting to create a shared_ptr.
Why is there no make_scoped() equivalent? Is there a common best practice?
Here’s a code example from the boost::scoped_ptr documentation that seems unsafe to me:
boost::scoped_ptr<Shoe> x(new Shoe);
This line of code will do these three things in order:
- Allocate heap memory for
Shoe - Call the constructor for
Shoe - Call the constructor for
boost::scoped_ptr<Shoe>
If the constructor for Shoe throws an exception, memory will be leaked. (see R. Martinho Fernandes answer) The scoped_ptr won’t handle the deallocation because it hasn’t been constructed yet.
Is this an oversight? Or is there a solution that I’ve failed to notice?
If the constructor fails, no memory is leaked. That’s part of the semantics of
new, no smart pointers involved:The added exception safety provided by
make_sharedcomes from when you’re initializing twoshared_ptrs in an expression and the two initializations are not sequenced, as is the case in function call arguments:Since there is no sequencing between the evaluations of
new Bar(true),shared_ptr<Bar>(new Bar(true)),new Bar(false)andshared_ptr<Bar>(new Bar(false)), the following could happen:new Bar(false)is evaluated and succeeds: memory is allocated;new Bar(true)is evaluated and fails: it doesn’t leak memory resulting from this evaluation;No
shared_ptrwas constructed at this time, and so the memory allocated in #1 is now leaked.