Der Wert an Speicheradresse 345686
– 0x0000002A – in hexadezimaler Schreibweise entspricht dabei der Zahl 42; da wir an die 3. Stelle im Array geschrieben haben (wir erinnern uns: Arrays sind 0-indiziert, der erste Index beginnt also bei 0, nicht bei 1), befindet sich der Wert entsprechend 8 Bytes (entspricht 2 Integer-Zahlen) hinter der Adresse, auf welche as
verweist.
War doch eigentlich ganz einfach, oder? 2 wichtige Dinge sind aber noch zu beachten!
Speicher, der auf dem Heap reserviert wurde, muss auch irgendwann wieder freigegeben werden. Stack-Speicher wird ja automatisch freigegeben, wenn das Ende der aktuell ausgeführte Funktion erreicht wird; mit dem Heap funktioniert das nicht so einfach, da der Compiler nicht dafür sorgt, dass reservierter Heap-Speicher nach dem Ende des Bereiches, wo er benutzt wird, automatisch freigegeben wird (den Grund hierfür werden wir auch später sehen). Die Freigabe muss also manuell erfolgen, wenn man nicht irgendwann sämtlichen verfügbaren Speicher verbraucht haben möchte (zwar wird der Speicher bei Programmende freigegeben, aber dann ist es oft zu spät). Dies geschieht über das Schlüsselwort delete[]
, etwa einfach so:
void f( int n ) { int* as = new int[n]; as[2] = 42; delete[] as; }
Ein wichtiger Hinweis: auf dem Heap reservierter Speicher muss immer freigegeben werden! Wird das nicht gemacht, hat man ein sogenanntes Speicherleck; Speicherlecks sorgen für einen hohen Arbeitsspeicherverbrauch und sind unter allen Umständen zu vermeiden.
Und ein zweiter Hinweis: C++ erlaubt die Deklaration mehrerer Variablen in einer einzelnen Zeile. Im folgenden Beispiel werden zum Beispiel 2 Integer-Variablen m
und n
deklariert:
int m, n;
Bei der Deklaration von Variablen, die Speicheradressen aufnehmen, gibt es leider eine etwas unschöne Sache in C++ (eine Altlast aus C-Zeiten; wer die Begründung für dieses Verhalten kennt, möge sich bitte in den Kommentaren melden). Schauen wir uns den folgenden Code an:
int* as, bs;
Der unbedarfte C++-Neuling wird hier wahrscheinlich vermuten, 2 Variablen as
und bs
deklariert zu haben, die zur Speicherung von Arrays verwendet werden. Leider ist dem nicht so: der Stern *
zur Markierung einer Adress-Variablen hängt am Namen der Variablen, nicht am zugehörigen Datentyp; as
nimmt also wirklich eine Adresse auf, bs
dagegen regulär eine ganze Zahl. Für 2 Adress-Variablen müssen wir das folgende schreiben:
int *as, *bs;
Ungewöhnlich, aber leider ist es so. Wo die Leerzeichen gesetzt werden, ist übrigens egal. Ich habe mir angewöhnt, bei Deklaration einer einzelnen Variablen den Stern an den Typ zu setzen, bei der Deklaration mehrerer Variablen den Stern an den Variablennamen – aber das kann jeder halten, wie er möchte.
Eine letzte Anmerkung: da mit dem Stern *
deklarierte Variablen Speicheradressen aufnehmen und daher auf eine bestimmte Adresse im Speicher verweisen – also darauf zeigen, spricht man bei derartigen Variablen dementsprechend von Zeigern, beziehungsweise englisch von Pointern.
Im nächsten Artikel werden wir dann sehen, was man mit Pointern noch alles anstellen kann – bleibt also gespannt! Und diesmal dauert es hoffentlich nicht wieder so lang.
Kommentare (8)