Namespaces
Variants

Lifetime

From cppreference.net

C 언어의 모든 객체 는 존재하며, 상수 주소를 가지며, 마지막으로 저장된 값을 유지합니다(값이 불확정적인 경우 제외) , 그리고 VLA의 경우 그 크기를 유지합니다 (C99부터) 프로그램 실행 중 객체의 수명 이라고 알려진 기간 동안.

자동, 정적, 스레드 저장 기간으로 선언된 객체들의 경우, 수명은 그들의 저장 기간 과 동일합니다 (비 VLA와 VLA 자동 저장 기간 사이의 차이점에 유의하세요).

할당된 저장 기간을 가진 객체들의 경우, 수명은 할당 함수가 반환될 때 시작되며( realloc 의 반환을 포함) realloc 또는 할당 해제 함수가 호출될 때 종료됩니다. 할당된 객체들은 선언된 타입 이 없으므로, 이 객체에 접근하기 위해 처음 사용된 lvalue 표현식의 타입이 해당 객체의 유효 타입 이 된다는 점에 유의하십시오.

객체의 수명 범위를 벗어난 접근은 정의되지 않은 동작입니다.

int* foo(void) {
    int a = 17; // a는 자동 저장 기간을 가짐
    return &a;
}  // a의 수명 종료
int main(void) {
    int* p = foo(); // p는 수명이 끝난 객체를 가리킴 ("댕글링 포인터")
    int n = *p; // 정의되지 않은 동작
}

수명이 종료된 객체(또는 객체의 한 칸 뒤)에 대한 포인터는 불확정값(indeterminate value)을 가집니다.

임시 객체 수명

배열 멤버(직접적이거나 중첩된 struct/union 멤버의 일부인)를 가진 struct 및 union 객체가 비-좌측값 표현식 으로 지정될 경우, 임시 수명 을 가집니다. 임시 수명은 해당 객체를 참조하는 표현식이 평가될 때 시작되며 다음 시퀀스 포인트 에서 끝납니다 (C11 이전) 포함하는 전체 표현식 또는 전체 선언자가 끝날 때 끝납니다 (C11 이후) .

임시 수명을 가진 객체를 수정하려는 모든 시도는 정의되지 않은 동작을 초래합니다.

struct T { double a[4]; };
struct T f(void) { return (struct T){3.15}; }
double g1(double* x) { return *x; }
void g2(double* x) { *x = 1.0; }
int main(void)
{
    double d = g1(f().a); // C99: UB g1 내에서 수명이 종료된 a[0] 접근
                          //      시퀀스 포인트에서 g1 시작 시점
                          // C11: OK, d는 3.15
    g2(f().a); // C99: UB 시퀀스 포인트에서 수명이 종료된 a[0] 수정
               // C11: UB 임시 객체 수정 시도
}

참고문헌

  • C17 표준 (ISO/IEC 9899:2018):
  • 6.2.4 객체의 저장 기간 (p: 30)
  • C11 표준 (ISO/IEC 9899:2011):
  • 6.2.4 객체의 저장 기간 (p: 38-39)
  • C99 표준 (ISO/IEC 9899:1999):
  • 6.2.4 객체의 저장 기간 (p: 32)
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 3.1.2.4 객체의 저장 기간

참고 항목

C++ 문서 for 객체 수명