Lebensdauer
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) über einen Teil der Programmausführung, der als *Lebensdauer* dieses Objekts bekannt ist.
Für die Objekte, die mit automatischer, statischer und Thread-Speicherdauer deklariert sind, entspricht die Lebensdauer ihrer Speicherdauer (beachten Sie den Unterschied zwischen nicht-VLA und VLA automatischer Speicherdauer).
Für die Objekte mit zugewiesener Speicherdauer beginnt die Lebensdauer, wenn die Zuweisungsfunktion zurückkehrt (einschließlich der Rückkehr von realloc) und endet, wenn die realloc- oder Freigabefunktion aufgerufen wird. Beachten Sie, dass zugewiesene Objekte keine deklarierte Art haben, so dass die Art des lvalue-Ausdrucks, der zuerst verwendet wird, um auf dieses Objekt zuzugreifen, zu seiner effektiven Art wird.
Der Zugriff auf ein Objekt außerhalb seiner Lebensdauer ist undefiniertes Verhalten.
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 }
Ein Zeiger auf ein Objekt (oder einen darüber hinausgehenden Zeiger), dessen Lebensdauer beendet ist, hat einen unbestimmten Wert.
[bearbeiten] Temporäre Lebensdauer
Struktur- und Union-Objekte mit Array-Mitgliedern (entweder direkt oder Mitglieder verschachtelter Struktur-/Union-Mitglieder), die durch Non-Lvalue-Ausdrücke bezeichnet werden, haben eine *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 umschließende vollständige Ausdruck oder die vollständige Deklaration 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 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 }
[bearbeiten] 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
[bearbeiten] Siehe auch
| C++ Dokumentation für Objektlebensdauer
|