c++c++11smart-pointersexception-safe

Can a unique_ptr<>() initialization fail?


From the documentation of std::unique_ptr<>(), what may happen when initializing the pointer is not clear to me.

When allocating an std::shared_ptr<>(), it allocates a memory buffer to handle the reference counter. So I may get an std::bad_alloc exception.

Could something similar happen when initializing a unique pointer?

I am asking the question because if it does, I may actually lose what I was attempting to have delete through the unique pointer. For example:

void deleter(FILE * f)
{
  fclose(f);
}

void func()
{
  ...
  FILE * f(fopen("/tmp/random", O_CREAT | ...));
  if(f == nullptr) ...handle error...
  std::unique_ptr<FILE, decltype(&deleter)> raii_file(f, deleter);
  ...
}

So, if the initialization of unique_ptr<>() can throw, I may end up keeping the file f open forever. (I use FILE * as an example, any similar resource could be affected.)

Opposed to this answer, I obviously cannot use std::make_unique<>() since I'm not just allocating memory.

Would it be safer to initialize the std::unique_ptr<>() before the fopen(), and then save the value in there after?

  ...
  std::unique_ptr<FILE, decltype(&deleter)> raii_file(nullptr, deleter);
  FILE * f(fopen("/tmp/random", O_CREAT | ...));
  if(f == nullptr) ...handle error...
  raii_file = f;
  ...

Or would that have similar problems?


Solution

  • All of unique_ptr's constructors are noexcept. So no, there's no way that it can fail. If your Deleter type throws on copy/move, then the noexcept will catch it and call std::terminate.