Einführung in C++ – Zeiger, Pointer,Referenzen – Teil2


Ein Zeiger ist eine Variable, die die Speicheradresse (des RAMs) einer anderen Variablen  enthält.

int i = 100;
int* pi = &i;
cout << pi; //Speicheradresse: z.B. 0x000026

Dereferenzieren von Zeigern: *Operator

  • auf den Wert zugreifen, auf den ein Zeiger(Pointer) zeigt
int i = 100;
int* pi = &i;
cout << *pi; //100
cout << pi; //Speicheradresse: z.B. 0x000026

void Zeiger

  • Zeiger auf unbekannten Typ -> dynamisch
  • muss gecastet werden bei Zugriff
int i=10;
void* pi;
pi=&i;
cout << *(int*) pi;

NULL-Zeiger

  • Speicher freigeben des Pointers, z.B. um Zombie Zeiger zu vermeiden, die auf nicht mehr existierende Objekte zeigen
int i = 100;
int* pi = &i;
pi = NULL;

Zeiger auf Konstanten

  • müssen auch const sein, damit nicht änderbar
const int i = 100;
const int* pi = &i;

Zeiger auf Funktionen

int f(float a){return 1;};
int (*pf)(float) = &f;
int x = (*pf)(1,5);

Zeiger bei Funktionen

Call by Value

  • Funktionswerte werden  kopiert, Übergabeparameter werden nicht dauerhaft geändert nur innerhalb der Funktion
  • um Werte ändern zu können müssen Referenzen übergeben werden (Call by Reference)
Bsp. char* strcpy(char* dest, const char* src));

Call By Reference

  • Parameter wird in der Funktion verändert dauerhaft
  • kein Kopieren der Parameter auf Stack
  • wenn Referenzen nicht verändert werden sollen, const setzen
Bsp. void f(int& a, const int& b);

Dynamische Speicher Allokation

  • Speicherreservierung zur Laufzeit, wenn der Speicherbedarf vorher unbekannt ist, z.B. bei Erzeugung von dynamischen Arrays mit unbekannter Länge

malloc()

  • liefert Zeiger auf void zurück, muss gecastet werden
  • Anzahl der Bytes übergeben
  • ohne Initialisierung vorher
char* s = (char*)malloc(5*sizof(char)); //char mit Platz für 5 Zeichen

free()

  • dynamischer Speicher sollte wieder freigegeben werden
  • oder automatisch am Ende des Programms
free(s); //Speicher freigeben
s = NULL; //Referent auf leeren Speicher entfernen (Zombie)

Calloc()

  • initialisiert den Speicher vorher
char* s = (char*)calloc(5*sizof(char)); //char mit Platz für 5 Zeichen

Realloc()

  • vergrößert/verkleinert dynamischen Speicher
char* sNew = (char*)realloc(s, 10*sizof(char)); //char mit Platz für 10 Zeichen von vorher 5

new-Operator

  • komfortabel, keine Größenberechnung in Bytes
  • Freigabe des Speichers mit delete[]
char* s = new char(5);
delete[] s;

Wo werden die Programmbestandteile im RAM gespeichert?

  1. Stack: Funktionsvariablen, vergrößert/verkleinert sich automatisch bei Aufruf nächster Funktion
  2. Stack Pointer: nächste frei Adresse
  3. Heap: globale Variablen und Code, dynamisch erstellter Speicher, um diesen Speicher sollte man sich selber kümmern

Die Reihenfolge der Speicheradressen ist verschieden, abhängig von der CPU Hardware. Intel CPU Small Endian, andere Big Endian.

int i = 100; //int werden als 2 Byte dargestellt, hexadezimal: 4*1 + 6*16 = 100

Big Endian Speicherabbild:

Speicheradresse / Wert
0x2000004 / 0x64
0x2000008 / 0x00

Small Endian Speicherabbild:

Speicheradresse / Wert
0x2000004 / 0x00
0x2000008 / 0x64

Inhaltsverzeichnis:

Einführung in C++ – Vorteile, Compiler, Namespaces – Teil1

Einführung in C++ – Zeiger, Pointer,Referenzen – Teil2

Einführung in C++ – Datentypen, Casting, Klassen – Teil3

Einführung in C++ – Funktionen und Operatoren überladen (Overloading) – Teil4

Einführung in C++ – Klassen: Vererbung, Adjustment, Friends, abstrakt – Teil5