Lifetime
C言語におけるすべての object は、存在し、一定のアドレスを持ち、(値が不定の場合を除き)最後に格納された値を保持し 、VLAについてはそのサイズを保持します (since C99) 。これらはプログラム実行中の一部期間、すなわちこのobjectの lifetime において維持されます。
自動、静的、およびスレッド記憶域期間で宣言されたオブジェクトについては、生存期間はそれらの storage duration と等しくなります(非VLAとVLAの自動記憶域期間の違いに注意してください)。
割り当てられた記憶域期間を持つオブジェクトについて、その生存期間は割り当て関数が返った時点( realloc からの返却を含む)から始まり、 realloc または解放関数が呼び出された時点で終了します。割り当てられたオブジェクトには declared type がないため、このオブジェクトにアクセスするために最初に使用されたlvalue式の型がその effective type となることに注意してください。
オブジェクトの生存期間外でのアクセスは未定義動作です。
int* foo(void) { int a = 17; // aは自動記憶域期間を持つ 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: 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++ documentation
for
Object lifetime
|
|
C++ documentation
の
Object lifetime
|