Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If make_shared/make_unique can throw bad_alloc, why is it not a common practice to have a try catch block for it?

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?

like image 236
Boanerges Avatar asked Jul 23 '19 07:07

Boanerges


1 Answers

I see two main reasons.

  1. 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?

  2. 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.

like image 159
lubgr Avatar answered Sep 20 '22 16:09

lubgr