Ihre Variable d
wird normalerweise nicht vom Stapel genommen. Geschweifte Klammern bezeichnen keinen Stapelrahmen. Andernfalls könnten Sie so etwas nicht tun:
char var = getch();
{
char next_var = var + 1;
use_variable(next_char);
}
Wenn geschweifte Klammern einen echten Stack-Push / Pop verursachen würden (wie es ein Funktionsaufruf tun würde), würde der obige Code nicht kompiliert werden, da der Code in den Klammern nicht auf die Variable zugreifen könnte var
, die außerhalb der Klammern lebt (genau wie ein Unter-) Funktion kann nicht direkt auf Variablen in der aufrufenden Funktion zugreifen). Wir wissen, dass dies nicht der Fall ist.
Geschweifte Klammern werden einfach zum Scoping verwendet. Der Compiler behandelt jeden Zugriff auf die "innere" Variable von außerhalb der umschließenden Klammern als ungültig und verwendet diesen Speicher möglicherweise für etwas anderes (dies ist implementierungsabhängig). Es kann jedoch nicht vom Stapel entfernt werden, bis die umschließende Funktion zurückkehrt.
Update: Hier ist, was die C-Spezifikation zu sagen hat. In Bezug auf Objekte mit automatischer Speicherdauer (Abschnitt 6.4.2):
Bei einem Objekt ohne Array-Typ variabler Länge erstreckt sich seine Lebensdauer vom Eintrag in den Block, dem es zugeordnet ist, bis die Ausführung dieses Blocks ohnehin endet.
Der gleiche Abschnitt definiert den Begriff "Lebensdauer" als (Schwerpunkt Mine):
Die Lebensdauer eines Objekts ist der Teil der Programmausführung, während dessen der Speicher garantiert dafür reserviert ist. Ein Objekt existiert, hat eine konstante Adresse und behält seinen zuletzt gespeicherten Wert während seiner gesamten Lebensdauer bei. Wenn auf ein Objekt außerhalb seiner Lebensdauer verwiesen wird, ist das Verhalten undefiniert.
Das Schlüsselwort hier ist natürlich "garantiert". Sobald Sie den Bereich des inneren Satzes von geschweiften Klammern verlassen, ist die Lebensdauer des Arrays abgelaufen. Möglicherweise wird noch Speicher dafür zugewiesen (Ihr Compiler verwendet den Speicherplatz möglicherweise für etwas anderes), aber alle Versuche, auf das Array zuzugreifen, rufen undefiniertes Verhalten hervor und führen zu unvorhersehbaren Ergebnissen.
Die C-Spezifikation kennt keine Stapelrahmen. Es spricht nur das Verhalten des resultierenden Programms an und überlässt die Implementierungsdetails dem Compiler (schließlich würde die Implementierung auf einer stapellosen CPU ganz anders aussehen als auf einer CPU mit einem Hardware-Stapel). In der C-Spezifikation gibt es nichts, was vorschreibt, wo ein Stapelrahmen enden wird oder nicht. Die einzige wirkliche Möglichkeit zu wissen , ist , den Code auf Ihre speziellen Compiler / Plattform zu kompilieren und die resultierende Anordnung zu untersuchen. Die aktuellen Optimierungsoptionen Ihres Compilers werden wahrscheinlich auch hier eine Rolle spielen.
Wenn Sie sicherstellen möchten , dass die Anordnung d
nicht mehr Speicher zu essen, während der Code ausgeführt wird , können Sie entweder den Code in geschweiften Klammern in eine separate Funktion umwandeln oder explizit malloc
und free
dem Speicher statt mit dynamischem Speicher.