Vorlesung „Programmieren“ Speicherverwaltung und Parameterübergabe Prof. Dr. Stefan Fischer Institut für Telematik, Universität zu Lübeck http://www.itm.uni-luebeck.de/people/fischer Gültigkeitsbereich von Variablen • Merkregeln – Variablen können an jeder Position im Code deklariert werden – Man unterscheidet globale und lokale Variablen – Gültigkeitsbereich erstreckt sich von der Position der Deklaration bis zum Ende des aktuellen Blocks – Gültigkeitsbereich wird auch Scope genannt • Jede Variable hat Gültigkeitsbereich und Speicherbereich – Speicher wird implizit (vom Compiler/Betriebssystem) oder – explizit (vom Programmierer) reserviert und freigegeben 5-2 Beispiel: globale und lokale Variablen Security - 04 Cryptology #3 Beispiel: Inverter args puffer zeichen index i 5-4 • Variante mit Prozeduren • Variablen und Parameter sind jeweils nur innerhalb der Prozedur gültig • Übergabe von Werten an aufgerufene Prozeduren Security - 04 Cryptology #5 Implizite Speicherverwaltung Security - 04 Cryptology #6 Implizite Speicherverwaltung • Speicher wird implizit durch Variablendeklarationen reserviert – Beispiel: int x; – Reserviert Speicher für eine int-Variable • Implizit: automatisch – Speicher wird automatisch zur passenden Zeit reserviert und dann wieder freigegeben – Erfolgt durch Compiler bzw. Betriebssystem – Keine manuelle Interaktion notwendig bzw. möglich Security - 04 Cryptology #7 Implizite Speicherverwaltung • Speicher wird durch Variablendeklarationen reserviert • Wichtig zum Verständnis: Zeitpunkte der Reservierung und Freigabe • Variablen existieren entweder – immer und genau einmal (statische Lebensdauer) – oder nur im aktiven Block Implizite Speicherverwaltung • Wo liegen Variablen, Parameter und Rückgabewerte im Speicher? Stack • Nicht die Variablen, sondern deren Werte werden auf den Stack abgelegt – Gilt in Java für alle primitiven Datentypen – Also nicht für Arrays und nicht-primitive Datentypen (z.B. Strings) – Prinzip des „call by value“ (vs. „call by reference“) • Adresse – Für sie wird Platz auf dem sog. Stack reserviert – Stack: Teil des Speicherbereichs eines Programms Spezielles Register: Stack pointer (SP) – Inhalt des Registers ist die Adresse des nächsten freien Stackeintrags SP 9 Implizite Speicherverwaltung: Beispiel • Variable „statisch“ – • • Variable „args“ und „c“ – Während Ausführung von main – Also quasi auch immer (main ist Hauptfunktion) Variable „b“ – • Existiert während gesamter Programmlaufzeit Nach Aufruf durch g() (Zeile 15) Variable „a“ – Nach Aufruf von f() (Zeile 10) – Nach Aufruf von f() (Zeile 16) Implizite Speicherverwaltung: Beispiel f() { int a; } static int statisch; main() { char c; g(); f(); } a(1) a(2) b c statisch Stack g() { float b; f(); } 11 Demo: Implizite Speicherverwaltung Security - 04 Cryptology #12 Implizite Speicherverwaltung und Rekursion • Beispiel: Rekursive Programmierung – Rekursion: Eine Funktion ruft sich selbst auf Was fehlt im dargestellten Stack? public static int f(int cnt) { if(cnt < 3) { return cnt + f(cnt + 1); } else { return cnt; } } public static void main(String args[]) { f(1); } cnt3= 3 cnt5= 2 cnt6= 1 Stack • 13 Wichtig: Abbruchbedingung bei Rekursion Security - 04 Cryptology #14 Aufgabe: ImpliziteSpeicherverwaltungAufgabe Security - 04 Cryptology #15 Explizite Speicherverwaltung Security - 04 Cryptology #16 Explizite (dynamische) Speicherverwaltung • Oft reicht implizite Reservierung nicht – Unbekannte Anzahl zur Compile-Zeit • Dann geht z.B. int[] x = new int[10]; nicht • Vielleicht ist dann so etwas notwendig: int[] x = new int[Integer.parseInt(args[0])]; – Langlebige aber nicht permanente Elemente • Wird z.B. über mehrere Funktionsaufrufe benötigt, aber nicht für die ganze Programmlaufzeit • Daher: dynamische Speicherverwaltung – Zu beliebigen Zeitpunkten Speicher anfordern und wieder freigeben – In Java: nur anfordern, Freigabe erfolgt automatisch 17 Explizite (dynamische) Speicherverwaltung • Speicher wird nicht auf dem Stack, sondern auf dem Heap reserviert Stack Heap • Heap und Stack teilen sich den Programmspeicher Heap • Heap und Stack wachsen aufeinander zu Stack 18 Beispiel für die Programmiersprache C • Funktion malloc reserviert Speicher – Gibt Anfangsadresse des reservierten Speichers zurück Funktion free gibt Speicher wieder frei – Anfangsadresse muss übergeben werden – Wenn man diese „vergessen“ hat, bleibt der Speicher „für immer“ reserviert 5000 4000 3000 2000 1000 • Beispiel – void* b1 = malloc(1000); void* b2 = malloc(2000); free(b1); free(b2); --b2 ----b1 Heap • 19 Explizite (dynamische) Speicherverwaltung • Erfolgt durch den Programmierer – Speicher kann nach Bedarf reserviert werden – Alle nicht-primitiven Datentypen müssen (in Java) so instanziiert werden • Variablen sind frei in Ihrer Gültigkeitsdauer – In vielen Sprachen muss Speicher explizit freigegeben werden – In Java erfolgt dies automatisch, wenn keine Referenz mehr auf diesen Bereich verweist Garbage Collection (später) • Wichtiges Schlüsselwort: new Schlüsselwort new • new reserviert so viel Speicher wie Datentyp benötigt • Beispiel: new int[100]; – Reserviert Speicherplatz für 100 int-Zahlen • Rückgabewert von new: Referenz auf erzeugtes Objekt – Datentyp der Rückgabe: wie angegeben (hier: int[]) Referenzen auf Speicherbereiche • a1, a2 und b sind Variablen, die auf ein int-Array verweisen können – – • Es werden zwei int-Arrays erzeugt und je eins wird a1 und a2 zugewiesen Damit referenziert jede Variable den neu reservierten Speicherbereich Die Variable b referenziert zunächst nichts – Für „nichts“ gibt es eine spezielle Adresse: null Beginn des Speicherbereichs Was bedeutet „null“? • Wörtlich: nichtig, ungültig – Bedeutet, dass diese Variable keinen Speicherbereich referenziert – Kann anstelle einer echten Speicherreferenz verwendet werden (Array, String, ...) – Nicht aber anstelle eines primitiven Wertes (boolean, int usw.) • Hinter null verbirgt sich kein Objekt im Speicher – Greift man denn darauf zu, wird ein Fehler erzeugt (NullPointerException später) Java: Reference Counting • Java: automatische Speicherfreigabe – Wird ein Speicherbereich nicht mehr über eine Variable referenziert, dann wird er freigegeben – Erfolgt periodisch und automatisch durch sog. Garbage Collector (GC) • Beispiel – int d1[] = new int[100]; // 1 Referenz int d2[] = d1; // 2 Referenzen d1 = null; // 1 Referenz d2 = null; // 0 Referenzen GC Auch der Heap ist endlich... Security - 04 Cryptology #25 • Größe von Heap und Stack können vorgegeben werden • Parameterübergabe an Java VM • Beispiel: java –Xmx128m –Xms256m MeinProg Security - 04 Cryptology #26 Call by Value vs. Call by Reference Security - 04 Cryptology #27 Call by Value vs. Call by Reference • Call by Value – – – – Übergabe von Werten an Funktionen Geschieht über den Stack Gilt für alle primitiven Datentypen in Java Veränderungen des Parameters wirken sich nur innerhalb der Funktion aus • Call by Reference – Übergabe von Referenzen auf den Speicherbereich – Veränderungen des Parameters wirken auch außerhalb der Funktion aus Security - 04 Cryptology #28 Beispiel: Call by Value • Übergabe von Werten (primitive Datentypen) Security - 04 Cryptology #29 Beispiel: Call by Reference • Verändern des übergebenen, referenzierten Speicherbereichs – Also Veränderung des übergeneben Parameters Security - 04 Cryptology #30 Beispiel: Call by Reference • Zuweisen eines neuen Speicherbereichs an den übergebenen Parameter Security - 04 Cryptology #31 Zusammenfassung und Ausblick • Variablen, Parameter und Rückgabewerte werden automatisch erzeugt und freigegeben – Implizite Speicherverwaltung über Stack • Parameter- und Rückgabewertübergabe erfolgt über Stack – Werte der primitiven Datentypen werden auf den Stack kopiert – Daten (Parameter, Rückgabe, Variablen) werden immer relativ zum Stack Pointer referenziert (erlaubt rekursive Aufrufe) – Nicht-primitive Datentypen: es wird eine Referenz (die Adresse im Speicher) übergeben • Speicher für nicht-primitive Datentypen muss explizit angefordert werden – Dynamische Speicherverwaltung über Heap – In Java wird reservierter Speicher automatisch freigegeben sobald keine Referenz mehr existiert (Garbage Collection) 5-32