0

Давайте предположим, что мы имеем следующий фрагмент кода:Определен внутренний порядок выполнения в параметрах функции?

void foo(std::unique_ptr<Data> p1, std::unique_ptr<Data> p2){ 
    bar(p1); 
    bar(p2); 
} 

int main(){ 
    foo(std::unique_ptr<Data>{new Data}, std::unique_ptr<Data>{new Data}); 
} 

Вопрос: будет ли память всегда быть освобождены от выполнения этого кода (независимо от того, что происходит)?

Стандарт говорит, что мы не можем полагаться на порядок утверждений, являющихся аргументами функции, но как насчет внутренних вызовов функций/распределения памяти и т. Д.? Это даже важно здесь?

ответ

7

память будет освобождена при запуске этого кода (независимо от того, что произойдет)?

Перед C++ 17: Нет. Один потенциальный порядок выполнения:

  1. оставил new Data
  2. правая new Data
  3. покинул unique_ptr конструктор
  4. правый unique_ptr конструктор

Если (1) броски, мы в порядке. Если (2) выбрасывает, мы пока еще не запускаем конструктор unique_ptr, поэтому у нас нет механизма очистки, чтобы освободить память из (1). Это будет утечка. Только в том случае, если ни один (1), ни (2) бросок не прекращаются.

Поэтому стандарт введен std::make_unique:

foo(std::make_unique<Data>(), std::make_unique<Data>()); 

, которая не имеет этой проблемы - new s теперь внутренне группируются в unique_ptr конструкторах. Поэтому, если кто-то преуспеет, он уже будет завернут в его защитник RAII.


После C++ 17: Да. Хотя порядок оценки аргументов функции по-прежнему не указан, существует новое правило, согласно которому такая оценка не может чередоваться. То есть, учитывая f(g(a), h(b)), потенциальные порядки оценки: [f, g, a, h, b] и [f, h, b, g, a]. Уже невозможно оценить как a, так и b до g или h, что было потенциальной проблемой с исходным кодом.

+0

Неплохая практика иметь конструкторы, которые могут бросать? – user3853544

+0

@ user3853544 'operator new' может выбрасывать – Caleth

+0

@ user3853544 Зависит: если вы всегда хотите иметь объекты в правильном состоянии (без конструирования, а затем проверки, являются ли они действительными), вы можете использовать их для этого. – Patryk

 Смежные вопросы

  • Нет связанных вопросов^_^