Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

C Tutorium – Memory Management – Knut Stolze. 2 Agenda Einführung in die Speicherverwaltung Stack vs. Heap Malloc Free Sizeof Tipps/Hinweise.

Ähnliche Präsentationen


Präsentation zum Thema: "C Tutorium – Memory Management – Knut Stolze. 2 Agenda Einführung in die Speicherverwaltung Stack vs. Heap Malloc Free Sizeof Tipps/Hinweise."—  Präsentation transkript:

1 C Tutorium – Memory Management – Knut Stolze

2 2 Agenda Einführung in die Speicherverwaltung Stack vs. Heap Malloc Free Sizeof Tipps/Hinweise

3 3 Speicherverwaltung Speicher (RAM) ist (meist) liniar und ein zusammenhängender Bereich – Muss unterteilt/strukturiert werden Alle Informationen (Daten und Programme) müssen im Hauptspeicher abgelegt werden Virtualisierung von Speicher – Erweiterung des physisch vorhandenen Hauptspeichers um Paging/Swap Space – Betriebssystem kümmert sich um Paging/Swapping

4 4 Speicherverwaltung (2) Programme können parallel laufen – Jedes Programm ist unabhängig von anderen – Speicher muss zugeteilt/reserviert werden – Jede Variable in einem Programm muss in einem zuvor reservierten Speicherbereich abgelegt werden! Prozess 1Prozess 3 Gesamter (virtueller) Speicher

5 5 Stack vs. Heap Speicher, der einem Programm insgesamt zur Verfügung steht HeapStack Stack-Pointer

6 6 Stack vs. Heap (2) Stack und Heap teilen sich gesamten zur Verfügung stehenden Speicher – Pro Prozess Heap: dynamisch benötigter Speicher Stack: statisch verwendeter Speicher

7 7 Stack Für alle statischen Informationen während des Programmablaufs – Wird zur Laufzeit allokiert – nicht beim Starten! Aufrufinformationen – Welche Funktion wurde von wo aufgerufen – Parameter der aufgerufenen Funktion – Rücksprungadresse Statische Variablen in der Funktion – Z.B. int a[50] Genügend Speicher für 50 “int” Werte – Werden automatisch beim Verlassen der Funktion aufgeräumt, d.h. der Speicher wird wieder freigegeben

8 8 Stack (2) Andere Programmiersprachen – C++: Destruktor von Objekten wird aufgerufen und Speicher wird freigegeben – Java: Reference count von Objekten auf dem Stack wird reduziert  garbage collector räumt auf Allokation auf dem Stack ist schneller/performanter als vom Heap – Heap kann Fragmentieren; Stack nicht

9 9 Heap Für dynamisch allokierten Speicher Wird vom Betriebssystem (OS) verwaltet – Funktion “malloc” fordert Speicherblock an Passender Block muss gesucht, reserviert und zurückgegeben werden – Funktion “free” gibt zuvor angeforderten Speicherblock wieder frei OS verwaltet alle angeforderten Speicherblöcke Speicher des Heaps kann fragmentieren

10 10 Ulimit (Unix) Legt Maximum von Resourcen für einen Prozess fest: – Maximal nutzbarer Speicherbereich (virtuell) – Größe des Stacks – Größe von “core” Dateien – Größe des “data segment” eines Prozesses – Größe von Dateien, die ein Prozess anlegen kann – Größe des ge”pin”ten SpeicherbereichsAnzahl der geöffneten Dateien – Blockgröße bei Pipes – Anzahl der Prozesse eines Nutzers – CPU-Zeit

11 11 Malloc Fordere einen Speicherblock vom Heap an ptr = malloc(size); – “ptr” ist ein Zeiger auf den Beginn des Speicherblocks Ein Zeiger ist eine Adresse im Hauptspeicher – “size” ist die Größe des Blocks in Anzahl von Bytes Speicherblock Heap im Hauptspeicher ptr (0x )

12 12 Malloc (2) Gibt Zeiger vom Typ “void *” zurück – Typ der Werte, die im Speicherblock hinterlegt werden sollen ist “malloc” nicht bekannt – Typ muss mittels Cast umgewandelt werden int *ptr = NULL; ptr = (int *)malloc(size); Es darf nicht ausserhalb des allokierten Speicherblocks zugegriffen werden – Speicher könnte anderen Prozessen oder anderen Datenstrukturen des gleichen Prozesses gehören

13 13 Malloc (3) Ähnliche Systemfunktionen: – calloc Andere Programmiersprachen verwenden ähnliche Operatoren, die Typisierung gleich mitliefern, d.h. der Cast wird intern gleich mit erledigt: – C++: Class *object = new Class(); – Java: Class object = new Class();

14 14 Grundlagen von Zeiger-Arithmetik Ergebnis von “malloc” zeigt auf 1 Element des spezifizierten Datentyps ptr = (int *)malloc(size); – “ptr” zeigt auf ein “int”-Wert Zeigerarithmetik arbeitet grundsätzlich auf dem zu Grunde liegenden Datentyp – “ptr = ptr + 1;” lässt den Zeiger auf den nächsten “int”- Wert zeigen (und nicht auf das zweite Byte)

15 15 Free Angeforderte Speicherblöcke müssen wieder freigegeben werden free(ptr); – Sobald nicht mehr gebraucht – Geschieht automatisch beim Programmende Zeiger auf Speicherblock darf bis zum “free” nicht verloren gehen! Ein Block kann nur genau 1x freigegeben werden – Mehrfache “free” Operationen könnten einen falschen Block freigeben – Danach darf Block nicht mehr verwendet werden

16 16 Free (2) Freigegebener Block (oder ein Teil davon) kann beim nächsten “malloc” wieder vergeben werden Andere Programmiersprachen verwenden intern auch “free”: – C++: delete-Operator – Java: garbage collection

17 17 Sizeof Operator Anzahl der Bytes von Datentypen kann von Plattform zu Plattform variieren – Z.B. unterschiedliche Größen von “int” Werten (32 vs. 64 Bit Prozessoren) – Unterschiedliche Optimierungsstrategien der Compiler – Unterschiedliche Mächtigkeit/Performance der Adressierungsbefehle des Prozessors – Zugriff auf Speicheradressen, die ein Vielfaches von 4 Bytes sind, oft schneller als Adressierung einzelner Bytes

18 18 Sizeof Operator (2)  Padding-Bytes können vom Compiler eingeschoben werden  Genaue Größe von Strukturen oft nicht bekannt oder soll nicht hart-verdrahtet werden (Portabilität)

19 19 Sizeof Operator (3) “sizeof” berechnet Größe eines Wertes oder eines Datentyps size = sizeof(int); size = sizeof(struct myStruct); size = sizeof myValue; – Anzahl an Bytes, die die physisch Repräsentation im Speicher benötigt ptr = (int *)malloc(N * sizeof(int)); Kann bereits zur Übersetzungszeit errechnet werden und belastet somit nicht die Laufzeit

20 20 Realloc Vorgrößern von Speicherblöcken ist nicht direkt möglich – Andere Speicherblöcke können physisch im Speicher direkt dahinter liegen int *ptr = NULL; int *biggerPtr = NULL; ptr = (int *)malloc(orig_size); … biggerPtr = (int *)realloc(ptr, new_size);

21 21 Memset, memcpy, memmove Angeforderte Speicherblöcke (malloc) sollten immer initialisiert werden memset(ptr, 0x00, size); – Bei sicherheitskritischen Anwendung ist ein “Leeren” vor dem Freigeben auch oft ratsam! Kopieren zwischen überlappungsfreien Speicherblöcken memcpy(destination, source, size); Kopieren zwischen überlappenden Speicherblöcken memmove(destination, source, size);

22 22 Richtlinien & Tipps Speicherallokation kann fehl schlagen!! – Ergebnis ist dann NULL-Zeiger – Ergebnis muss immer überprüft werden Speicherblock nach “free” nicht weiter verwenden – Am besten Zeiger auf NULL setzen: free(ptr); ptr = NULL

23 23 Richtlinien & Tipps (2) Alle Variablen sofort bei der Deklaration initialisieren char *str = NULL; int counter = 0; str = (char *)malloc(strlen(orig_str)+1); if (!str) { … } memset(str, 0x00, strlen(orig_str)+1);

24 24 Potientielle Probleme Keine gute Kontrolle über Speicher – Keine Gruppierung von Speicher – Keine Fehlermeldung beim falschen Freigeben  Programm stürzt eventuell ab; vielleicht auch an ganz anderer Stelle Buffer Overflow verhindern – Zugriff ausserhalb des aktuellen Speicherblocks – Oft keine/unzureichende Prüfung von Überläufen – Kann sich oft zu Sicherheitsproblemen ausweiten

25 25 Potentielle Probleme (2) Memory Leaks – angeforderter Speicher wird nie freigegeben – Zeiger auf Speicherblock ist verloren gegangen Funktionen dürfen keinen Zeiger in den Stack zurückgeben – Informationen auf dem Stack sind beim Verlassen der Funktion nicht mehr gültig “free” auf Objekt auf dem Stack ist nicht zulässig – Führt meist zum Absturz des Programms


Herunterladen ppt "C Tutorium – Memory Management – Knut Stolze. 2 Agenda Einführung in die Speicherverwaltung Stack vs. Heap Malloc Free Sizeof Tipps/Hinweise."

Ähnliche Präsentationen


Google-Anzeigen