The CppReference page for make_shared says (same with make_unique)
May throw std::bad_alloc or any exception thrown by the constructor of T. If an exception is thrown, the functions have no effect.
This means that std::bad_alloc exeception can be thrown in case of a failure. "the functions have no effect" implicitly means that it cannot return a nullptr. If this is the case, why is it not a common practice to write make_shared/make_unique always into a try catch block?
What is the proper way to use a make_shared? Within try catch block? or Checking for nullptr?
I see two main reasons.
Failure of dynamic memory allocation is often considered a scenario which doesn't allow for graceful treatment. The program is terminated, and that's it. This implies that we often don't check for every possible std::bad_alloc
. Or do you wrap std::vector::push_back
into a try-catch block because the underlying allocator could throw?
Not every possible exception must be caught right at the immediate call side. There are recommendations that the relation of throw
to catch
shall be much larger than one. This implies that you catch exceptions at a higher level, "collecting" multiple error-paths into one handler. The case that the T
constructor throws can also be treated this way. After all, exceptions are exceptional. If construction of objects on the heap is so likely to throw that you have to check every such invocation, you should consider using a different error handling scheme (std::optional
, std::expected
etc.).
In any case, checking for nullptr
is definitely not the right way of making sure std::make_unique
succeeds. It never returns nullptr
- either it succeeds, or it throws.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With