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 : Nope. 실행의 하나 개의 잠재적 인 순서는 다음과 같습니다

  1. new Data
  2. unique_ptr 생성자 (1)가 발생하는 경우, 우리는 괜찮아요

  • 바로 unique_ptr 생성자를 왼쪽 new Data
  • 을 떠났다. (2) throw되면, 우리는 아직 실제로 unique_ptr 생성자를 실행하지 않았으므로 (1)에서 메모리를 해제 할 정리 메커니즘이 없습니다. 그건 누출 될거야. (1)도 (2)도 던지지 않는 경우에만 괜찮습니다. 표준이 std::make_unique를 도입하는 이유

    입니다 :이 문제가되지 않습니다

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

    일 - new의 현재 내부적으로 unique_ptr 생성자로 그룹화됩니다. 따라서 하나가 성공하면 이미 RAII 가드에 싸여있을 것입니다.


    후 C++ 17 : 예. 함수 인수의 평가 순서는 아직 지정되지 않았지만 이러한 평가를 인터리브 할 수 없다는 새로운 규칙이 있습니다. 즉, f(g(a), h(b))이 주어지면 잠재적 인 평가 순서는 [f, g, a, h, b][f, h, b, g, a]입니다. 더 이상 abg 또는 h 전에 평가할 수 없으므로 원래 코드의 잠재적 인 문제점이었습니다.

  • +0

    던질 수있는 생성자를 갖는 것이 바람직하지 않습니까? – user3853544

    +0

    @ user3853544'operator new'는 – Caleth

    +0

    @ user3853544를 던질 수 있습니다. 의존 : 당신이 항상 유효한 상태에있는 객체를 가지고 있고 (구성 및 유효성 검사를하지 않고) 객체를 갖고 싶다면이 객체를 사용할 수 있습니다. – Patryk

    관련 문제