生存期
來自 cppreference.com
C 語言中,每個物件在程式執行的某個時段記憶體在,擁有一個不變的地址,並保留其最後儲存的值(除非該值為不確定的),對於變長陣列(VLA),還會保留其大小(C99 起)。這個時段被稱為該物件的生命週期。
對於宣告為具有自動、靜態和執行緒儲存期的物件,其生命週期等於它們的儲存期(注意非 VLA 和 VLA 自動儲存期之間的區別)。
對於具有已分配儲存期的物件,其生命週期始於分配函式返回時(包括 realloc 的返回),終止於呼叫 realloc 或解除分配函式時。請注意,由於已分配物件沒有宣告型別,因此首次用於訪問該物件的左值表示式的型別會成為其有效型別。
在物件的生命週期之外訪問物件是未定義行為。
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 }
指向生命週期已結束的物件的指標(或指向物件末尾之外一個位置的指標)具有不確定值。
[編輯] 臨時生命週期
由非左值表示式指定的,含有陣列成員的結構體和聯合體物件(無論是直接成員還是巢狀結構體/聯合體成員的成員)具有臨時生命週期。臨時生命週期始於引用此類物件的表示式被求值時,並結束於下一個序列點(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++ 文件 關於 物件生命週期
|