Typische Speicherfehler in C



Ähnliche Dokumente
Typische Speicherfehler in C

Crashkurs C++ - Teil 1

Debugging und Speicherfehler. Seminar Effiziente Programmierung Kadir Duman

Dynamische Speicherverwaltung

Software Entwicklung 1

C- Kurs 08 Zeiger. Dipl.- Inf. Jörn Hoffmann leipzig.de. Universität Leipzig Ins?tut für Informa?k Technische Informa?

Proseminar - Zeiger in C

C/C++-Programmierung

C++ Teil 5. Sven Groß. 13. Mai Sven Groß (IGPM, RWTH Aachen) C++ Teil Mai / 18

Zeiger, Arrays und Strings in C und C++

Programmierung mit C Zeiger

Programmieren in C/C++ und MATLAB

C++ - Einführung in die Programmiersprache Zeiger, Referenzen und Strukturen. Leibniz Universität IT Services Anja Aue

Probeklausur Name: (c)

INE1 Arrays, Zeiger, Datenstrukturen

Übungspaket 29 Dynamische Speicherverwaltung: malloc() und free()

Seminar Effiziente Programmierung Debugging und Speicherfehler

Grundlagen der Informatik 11. Zeiger

Übungspaket 23 Mehrdimensionale Arrays

Übersicht. Speichertypen. Speicherverwaltung und -nutzung. Programmieren in C

Vorlesung Programmieren

Arrays (Felder/Vektoren)

1 wsort - Datenstrukturen (1. Möglichkeit)

Exploit-Entwicklung mit Python

Pointer. Variablen. Pointer. Ein elementares Beispiel. Pointer in C

Einleitung Grundlagen Erweiterte Grundlagen Zusammenfassung Literatur. C: Funktionen. Philip Gawehn

Einführung in die Programmierung zusammengesetzte Datentypen, dynamischer Speicher

Modellierung und Programmierung 1

Übungspaket 23 Mehrdimensionale Arrays

Speichermanagement Software Entwicklung 1

F Zeiger, Felder und Strukturen in C

Zeiger: Der Adressoperator &

C++ Teil 5. Sven Groß. 8. Mai IGPM, RWTH Aachen. Sven Groß (IGPM, RWTH Aachen) C++ Teil 5 8. Mai / 16

Verschlüsseln eines Bildes. Visuelle Kryptographie. Verschlüsseln eines Bildes. Verschlüsseln eines Bildes

Variablen. Deklaration: «Datentyp» «Variablenname» Datentyp bestimmt Größe in Bytes: sizeof Beispiel: long int v; Größe: 4 Bytes

Programmieren in C. Speicher anfordern, Unions und Bitfelder. Prof. Dr. Nikolaus Wulff

Übungspaket 14 Eindimensionale Arrays

Dynamische Speicherverwaltung

Teil 5: Felder, Zeiger, Zeigerarithmetik Gliederung

9 Zeiger (Pointer). Dynamischer Speicher

Dynamischer Speicher

Felder (Arrays) und Zeiger (Pointers) - Teil I

int i=1; //Integerzahl i anlegen und mit 1 initialisieren float wert; //Floatzahl deklarieren scanf( %f,&wert); //Wert über Tastatur eingeben

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny

Programmiersprachen Einführung in C

Algorithmen und Datenstrukturen

U4-1 Aufgabe 3: einfache malloc-implementierung

Zeiger in C und C++ Zeiger in Java und C/C++

Praxis der Programmierung

Funktionen, Zeiger und Arrays in C Software Entwicklung 1

Datenfelder (Arrays) Vektoren, Matrizen, Tabellen. Dr. Beatrice Amrhein

Javaprogrammierung mit NetBeans. Variablen, Datentypen, Methoden

Einführung in C. Alexander Batoulis. 5. Mai Fakutltät IV Technische Universität Berlin

Vorkurs C++ Programmierung

Übungspaket 29 Dynamische Speicherverwaltung: malloc() und free()

Dynamische Datentypen. Destruktor, Copy-Konstruktor, Zuweisungsoperator, Dynamischer Datentyp, Vektoren

einlesen n > 0? Ausgabe Negative Zahl

Schleifen Datenfelder (Arrays) Verzweigungen

C-Kurs 2011: Arrays, Strings, Pointer

Herzlich willkommen!

Teil 5: Zeiger, Felder, Zeichenketten Gliederung

2. Programmierung in C

Zeiger in C und C++ Zeiger in Java und C/C++

Einleitung Entwicklung in C Hello-World! Konstrukte in C Zusammenfassung Literatur. Grundlagen von C. Jonas Gresens

Programmierkurs C++ Datenstrukturen Seite 1

Advanced Programming in C

ÜBUNGS-BLOCK 7 LÖSUNGEN

ESP Tutorium. Studienassistent: Ewald Moitzi. Gruppe 1

Dynamische Speicherverwaltung

printf("%c \n", 'd'); printf("%lx \n", 32L); printf("%o \n", 64); printf("%f \n", 1.0E-2); printf("%d \n", '\r'); printf("%f \n", 1.0/2.

DAP2 Praktikum Blatt 1

Dynamisches Speichermanagement

Universität München, Hans-Peter Kriegel und Thomas Seidl Informatik II a[0] a[1] a[2] a[3] a[n 1]

Einstieg in die Informatik mit Java

II. Grundlagen der Programmierung. Beispiel: Merge Sort. Beispiel: Merge Sort (Forts. ) Beispiel: Merge Sort (Forts. )

Praxisorientierte Einführung in C++ Lektion: "Dynamische Speicherverwaltung"

Transkript:

Typische Speicherfehler in C Thorsten Ploß Informatik Universität Hamburg Proseminar: C-Grundlagen und Konzepte 17.05.2013 1 / 13

Inhaltsverzeichnis Einleitung Klassische Speicherverwaltung - Fehlerquellen Nicht initialisierte Variablen Der Gültigkeitsbereich Das Ende des Arrays Dynamische Speicherverwaltung - Fehlerquellen Null-Pointer Pointerprobleme Speicherlecks Benutzung nach Freigabe und doppelte Freigabe Zusammenfassung Quellenverzeichnis 2 / 13

Einleitung Speicherfehler in C sind ein sehr relevantes Thema: Sehr direkter Einfluss auf den Speicher Fehler bieten Angreifern Schwachstellen Zufällig können Daten verändert werden Wenige Automatismen zur Speicherverwaltung Einsatz in heiklen Situationen Lebensgefahr Große Geldverluste Fehlerquellen oft nur sehr aufwendig ermittelbar 3 / 13

Nicht initialisierte Variablen Kein definierter Wert nach der Deklaration Kein Zwang zu initialisieren Je nach Compiler unbemerkt bei Pointern besteht die Gefahr, unbestimmte Speicherbereiche zu verändern 3 int t; 4 int array[2]; 5 char c;//ein paar Variablen 6 7 int main(int argc, char *argv[]){ 8 int i; 9 char b;//ein paar weitere Variablen 10 printf("%d %d %d %c %d %c", t,array[0],array[1],c,i,b); 11 return(0); //Was da wohl raus kommt? 12 } 4 / 13

Der Gültigkeitsbereich 3 int a = 0; 4 Variablen sind nur innerhalb ihres Anweisungsblocks erreichbar Folge: Zugriff auf Variable eines anderen Blocks schlägt fehl In inneren des Anweisungsblocks Variablen verschatten Neue Variable mit gleichem Namen Verhindert innerhalb des Blocks Zugriff auf die andere Variable Nach dem Block ist die alte Variable unverändert Folge: Werte gehen verloren 5 int main(int argc, char *argv[]){ 6 if(argc > 0){ 7 double result = argc/4; 8 int a = 9; 9 } 10 printf("ein Viertel von argc ist %f \n",result); 11 printf("a ist 9? %d \n",a); 12... 5 / 13

Das Ende des Array Arrays basieren auf Pointern Keine Zugriffskontrolle Daher versehentlicher Zugriff auf andere Speicherbereiche möglich Bestehendes Risiko Einfluss auf die Rücksprungadresse zu nehmen 3 int array[5]; 4 int t; 5 6 int main(int argc, char *argv[]){ 7 t = 42; 8 printf("die Antwort lautet: %d\n",array[5]); 9 //Ein Index zu weit und die Wahrheit ist berechnet... 10 printf("irgendwo im Speicher steht %d\n", array[123]); 11 return(0); 12 } 6 / 13

Inhaltsverzeichnis Einleitung Klassische Speicherverwaltung - Fehlerquellen Nicht initialisierte Variablen Der Gültigkeitsbereich Das Ende des Arrays Dynamische Speicherverwaltung - Fehlerquellen Null-Pointer Pointerprobleme Speicherlecks Benutzung nach Freigabe und doppelte Freigabe Zusammenfassung Quellenverzeichnis 7 / 13

Null-Pointer Fehlgeschlagene Allokation Fehlende Initialisierung Resultate Pointer auf unerwünschte Adresse Versuchter Zugriff auf Kernel-Speicher Segmentation Error 8 / 13

Pointerprobleme Adresszuweisung statt Wertzuweisung entsteht schnell durch Tippfehler Resultat: Pointer auf unbekannte Adresse Allocation mit unzureichend viel Speicher Annahmen über benötigte Speichermenge int braucht meist mehr als 2 Byte 3 int BUFF = 80; 4 int *t,f = 8;; 5 6 int main(int argc, char *argv[]){ 7 t = (int *)malloc(2); 8 *t = 4; //In t soll 4 gespeichert werden 9 char *array = (char *)malloc(sizeof(char)*buff);//kein Chararray der Welt ist laenger als 80 Zeichen! 10 t = &f; //oder soll in t doch lieber 8 gespeichert werden? 11 return(0); 12 } 9 / 13

Speicherlecks 3 int *a; 4 Speicher nicht wieder freigeben Bleibt lange unbemerkt Kann für programmübergreifende Schwierigkeiten sorgen Hinterhältigster aller Speicherfehler 5 int main(int argc, char *argv[]) 6 { 7 while(1) 8 { 9 a = (int *)malloc(sizeof(int)); 10 } 11 return(0); 12 } 10 / 13

Benutzung nach Freigabe und Doppelte Freigabe 3 int *p; 4 int *z; 5 Einen Pointer nach seiner Freigabe nutzen Führt zu undefiniertem Verhalten Kann den Wert von anderen Pointern verändern Einen Pointer doppelt freigeben Führt zum Laufzeitfehler 6 int main(int argc, char *argv[]){ 7 p = (int *)malloc(sizeof(int)); 8 *p = 1337; 9 free(p); 10 z = (int *)malloc(sizeof(int)); 11 *z = 8; 12 *p = 42; 13 printf("eine Spinne hat %d Beine\n",*z); 14 free(p); 15 return(0); 16 } 11 / 13

Zusammenfassung Fehler machen ist leicht Fehler beheben ist schwer Viel kann Schaden nehmen Warnungen sind essentiell Werkzeuge wie Valgrind können helfen Abbildung: Compiler Complaint; Quelle:http://xkcd.com/371/ 12 / 13

Quellenverzeichnis http://www.peace-software.de/ckurs12.html [Stand: 13.05.2013] http://pronix.linuxdelta.de/c/standard C/ c programmierung 17.shtml [Stand: 13.05.2013] http://de.wikibooks.org/wiki/c- Programmierung: Speicherverwaltung [Stand: 13.05.2013] https://de.wikipedia.org/wiki/speicherleck [Stand: 13.05.2013] http://c-buch.sommergut.de/kapitel10/g%fcltigkeitsbereich-von- Variablen.shtml [Stand: 13.05.2013] Bild auf Folie 11: http://xkcd.com/371/ [Stand 13.05.2013] 13 / 13