Lifetime
Jedes Objekt in C existiert, hat eine konstante Adresse, behält seinen zuletzt gespeicherten Wert (außer wenn der Wert unbestimmt ist) , und, für VLA, behält seine Größe (seit C99) während eines Teils der Programmausführung, der als Lebensdauer dieses Objekts bekannt ist.
Für Objekte, die mit automatischer, statischer und Thread-Speicherdauer deklariert werden, entspricht die Lebensdauer ihrer Speicherdauer (beachten Sie den Unterschied zwischen nicht-VLA und VLA automatischer Speicherdauer).
Für Objekte mit zugewiesener Speicherdauer beginnt die Lebensdauer, wenn die Allokationsfunktion zurückkehrt (einschließlich der Rückkehr von realloc ) und endet, wenn realloc oder die Deallokationsfunktion aufgerufen wird. Beachten Sie, dass zugewiesene Objekte keinen deklarierten Typ haben, daher wird der Typ des Lvalue-Ausdrucks, der erstmals für den Zugriff auf dieses Objekt verwendet wird, zu seinem effektiven Typ .
Der Zugriff auf ein Objekt außerhalb seiner Lebensdauer ist undefiniertes Verhalten.
int* foo(void) { int a = 17; // a hat automatische Speicherdauer return &a; } // Lebensdauer von a endet int main(void) { int* p = foo(); // p zeigt auf ein Objekt nach Lebensdauerende ("dangling pointer") int n = *p; // undefiniertes Verhalten }
Ein Zeiger auf ein Objekt (oder eins hinter dem Objekt), dessen Lebensdauer beendet wurde, hat einen unbestimmten Wert.
Temporäre Lebensdauer
Struct- und Union-Objekte mit Array-Mitgliedern (entweder direkt oder als Mitglieder verschachtelter Struct-/Union-Mitglieder), die durch Nicht-Lvalue-Ausdrücke bezeichnet werden, haben temporäre Lebensdauer . Die temporäre Lebensdauer beginnt, wenn der Ausdruck, der sich auf ein solches Objekt bezieht, ausgewertet wird, und endet am nächsten Sequenzpunkt (bis C11) wenn der enthaltende vollständige Ausdruck oder vollständige Deklarator endet (seit C11) .
Jeder Versuch, ein Objekt mit temporärer Lebensdauer zu modifizieren, führt zu undefiniertem Verhalten.
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 Zugriff auf a[0] in g1, dessen Lebensdauer endete // am Sequenzpunkt zu Beginn von g1 // C11: OK, d ist 3.15 g2(f().a); // C99: UB Modifikation von a[0], dessen Lebensdauer am Sequenzpunkt endete // C11: UB Versuch, ein temporäres Objekt zu modifizieren }
Referenzen
- C17-Standard (ISO/IEC 9899:2018):
-
- 6.2.4 Speicherdauer von Objekten (S: 30)
- C11-Standard (ISO/IEC 9899:2011):
-
- 6.2.4 Speicherdauer von Objekten (S: 38-39)
- C99-Standard (ISO/IEC 9899:1999):
-
- 6.2.4 Speicherdauer von Objekten (S: 32)
- C89/C90 Standard (ISO/IEC 9899:1990):
-
- 3.1.2.4 Speicherdauer von Objekten
Siehe auch
|
C++ Dokumentation
für
Objektlebensdauer
|