2016-11-06 3 views
0

Из документации std::unique_ptr<>(), что может случиться, когда инициализация указателя мне не понятна.Ошибка инициализации unique_ptr <>()?

При назначении std::shared_ptr<>() он выделяет буфер памяти для обработки эталонного счетчика. Поэтому я могу получить исключение std::bad_alloc.

Может ли что-то подобное произойти при инициализации уникального указателя?

Я задаю вопрос, потому что, если это так, я могу фактически потерять то, что пытаюсь удалить с помощью уникального указателя. Например:

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); 
    ... 
} 

Таким образом, если инициализация unique_ptr<>() может бросить, я могу закончить сохранение файла f открытым навсегда. (Например, в качестве примера можно использовать FILE *).

Против this answer, я, очевидно, не могу использовать std::make_unique<>(), так как я не просто выделяю память.

Было бы безопаснее инициализировать std::unique_ptr<>() перед fopen(), а затем сохранить значение там после?

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

Или у этого были бы подобные проблемы?

+1

'std _ :: unique_ptr' ctor is' noexcept', в соответствии с документами, которые вы связали. – BadZen

+0

@BadZen, я думаю, мне нужно научиться правильно читать документацию. Я ожидал увидеть это в декларации наверху. –

+0

Да, форматирование немного грубо ... = / – BadZen

ответ

4

Все конструкторы unique_ptr: noexcept. Так что нет, нет никакого способа, чтобы это могло потерпеть неудачу. Если ваш тип Deleter бросает на копирование/перемещение, то noexcept поймает его и вызовет std::terminate.