Alexis Wilke Alexis Wilke - 1 month ago 8
C++ Question

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?

Answer

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.