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