名前空間
変種
操作

生存期間

提供: cppreference.com
< c‎ | language

C の存在するすべてのオブジェクトは、プログラム実行中の生存期間と呼ばれる期間の間、固定のアドレスを持ち、最後に格納された値 (不定のときは除きます) およびそのサイズ (VLA の場合) (C99以上) を保持します。

自動、静的、およびスレッド記憶域期間を持つように宣言されたオブジェクトの場合、生存期間はその記憶域期間と同じです (非 VLA と VLA の自動記憶域期間の違いに注意してください)。

確保された記憶域期間を持つオブジェクトの場合、生存期間は確保関数 (realloc も含みます) が返ったときに始まり、 realloc または解放関数が呼ばれたときに終わります。 確保されたオブジェクトには宣言された型がないため、そのオブジェクトにアクセスするために最初に使用された左辺値式の型がその実効型になります。

生存期間外のオブジェクトのアクセスは未定義動作です。

int* foo(void) {
    int a = 17; // 自動記憶域期間を持ちます。
    return &a;
}  // a の生存期間が終わります。
int main(void) {
    int* p = foo(); // p は生存期間が過ぎたオブジェクトを指しています (「ダングリングポインタ」)。
    int n = *p; // 未定義動作。
}

生存期間が終わったオブジェクト (またはその次のオブジェクト) へのポインタは不定値を持ちます。

[編集] 一時的な生存期間

非左辺値式によって指示されている配列メンバを (直接またはネストした構造体/共用体のメンバとして) 持つ構造体および共用体オブジェクトは一時的な生存期間を持ちます。 一時的な生存期間はそのようなオブジェクトを参照する式が評価されたときに始まり、次の副作用完了点 (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: g1 の始まりの副作用完了点で生存期間が終わる g1 内の
                          //      a0[0] へのアクセスは未定義動作です。
                          // C11: OK、 d は 3.15 です。
    g2(f().a); // C99: 副作用完了点で生存期間が終わる a[0] の変更は未定義動作です。
               // C11: 一時オブジェクトを変更する試みは未定義動作です。
}

[編集] 参考文献

  • C11 standard (ISO/IEC 9899:2011):
  • 6.2.4 Storage durations of objects (p: 38-39)
  • C99 standard (ISO/IEC 9899:1999):
  • 6.2.4 Storage durations of objects (p: 32)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 3.1.2.4 Storage durations of objects

[編集] 関連項目

オブジェクトの生存期間C++リファレンス