Zeiger und Speicher

Zeiger und Adressen in C und C++

In dieser Lektion speicherst du die Adresse einer Variablen in einem Zeiger, greifst über den Zeiger auf den Wert zu und änderst die ursprüngliche Variable.

Einführung

Ein Zeiger (pointer) ist eine Variable, die die Speicheradresse einer anderen Variablen enthält. Der Operator & liefert die Adresse einer Variablen, und der Operator * (Dereferenzierung) greift auf den Wert an der Adresse zu, auf die der Zeiger zeigt. Zeiger gehören zu den wichtigsten Konzepten von C und C++.

Wichtige Punkte

  • Ein Zeiger darf nur auf ein noch existierendes Objekt des richtigen Typs zeigen oder null sein.
  • Jeder reservierte Speicherbereich muss genau einmal freigegeben werden.
  • Mache deutlich, welche Funktion den Speicher besitzt (ownership) und welche Daten nur gelesen werden (const).

Codebeispiele in C und C++

C
Code ausführen →
main.c
#include <stdio.h>

int main(void) {
    int score = 70;
    int *score_ptr = &score;
    *score_ptr += 5;
    printf("score=%d same-address=%s\n", score,
           score_ptr == &score ? "yes" : "no");
    return 0;
}
Ergebnis der Ausführung
score=75 same-address=yes
C++
Code ausführen →
main.cpp
#include <iostream>

int main() {
    int score = 70;
    int* score_ptr = &score;
    *score_ptr += 5;
    std::cout << "score=" << score << " same-address="
              << std::boolalpha << (score_ptr == &score) << '\n';
}
Ergebnis der Ausführung
score=75 same-address=true

C und C++ im Vergleich

Der Zeiger score_ptr enthält die Adresse von score, deshalb addiert *score_ptr += 5 in Wirklichkeit 5 zur Variablen score selbst, die von 70 auf 75 steigt. Der Vergleich score_ptr == &score bestätigt, dass beide Adressen dieselbe sind. C++ verwendet weiterhin einfache Zeiger (raw pointer), wenn nur zugegriffen, aber kein Speicher verwaltet wird, bevorzugt aber Referenzen, wenn die Variable nie leer sein darf.

C

Besitz und Freigabe von Speicher muss der Programmierer vollständig selbst sicherstellen.

C++

Container und RAII geben Ressourcen automatisch frei, wenn die Lebensdauer des Objekts endet.

Übungen zur Vertiefung

Führe beide Versionen aus und ändere dann den Code, um zu beobachten, welche Sicherheit jede Sprache bietet.

  • Teste mit Nullzeigern und fehlgeschlagener Speicherreservierung.
  • Führe das Programm mit AddressSanitizer und UndefinedBehaviorSanitizer aus, um Speicherfehler zu finden.
  • Notiere klar, welcher Zeiger den Speicher besitzt und welcher nur zum Lesen dient.

Mit einer Challenge üben

Nutze den Inhalt dieser Lektion, um ein echtes Problem zu lösen. Jede Challenge läuft im Browser, mit sofortigen Tests und einem KI-Review.

Alle Challenges