名前空間
変種
操作

生存期間

From cppreference.com
< c‎ | language

C言語のすべてのオブジェクトは、プログラム実行の一部である「ライフタイム」の間、一定のアドレスを持ち、最後に格納された値を保持します(値が不定である場合を除く)。VLAについては、サイズも保持します(C99以降)

自動ストレージ期間、静的ストレージ期間、スレッドストレージ期間で宣言されたオブジェクトのライフタイムは、そのストレージ期間に等しくなります(VLAではない自動ストレージ期間とVLAの自動ストレージ期間の違いに注意してください)。

割り当てられたストレージ期間を持つオブジェクトの場合、ライフタイムは割り当て関数が返ったとき(reallocからの戻りを含む)に始まり、reallocまたは解放関数が呼び出されたときに終了します。割り当てられたオブジェクトには宣言された型がないため、このオブジェクトに最初にアクセスするために使用されるlvalue式の型が、その実効型となることに注意してください。

オブジェクトのライフタイム外でアクセスすることは、未定義の動作です。

int* foo(void) {
    int a = 17; // a has automatic storage duration
    return &a;
}  // lifetime of a ends
int main(void) {
    int* p = foo(); // p points to an object past lifetime ("dangling pointer")
    int n = *p; // undefined behavior
}

ライフタイムが終了したオブジェクト(またはそのオブジェクトの次)へのポインタは、不定な値となります。

[編集] 一時ライフタイム

配列メンバーを持つ構造体および共用体オブジェクト(直接またはネストされた構造体/共用体メンバーのメンバーである場合)が、非lvalue式によって指定される場合、「一時ライフタイム」を持ちます。一時ライフタイムは、そのようなオブジェクトを参照する式が評価されたときに始まり、次のシーケンスポイントまで続きます(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 access to a[0] in g1 whose lifetime ended
                          //      at the sequence point at the start of g1
                          // C11: OK, d is 3.15
    g2(f().a); // C99: UB modification of a[0] whose lifetime ended at the sequence point
               // C11: UB attempt to modify a temporary object
}

[編集] 参考文献

  • 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++ドキュメント (オブジェクトのライフタイム)
English 日本語 中文(简体) 中文(繁體)