Zeiger und Speicher

Zeigerarithmetik in C und C++

In dieser Lektion durchläufst du die Elemente eines Arrays mit Zeigerarithmetik in C und mit Iteratoren in C++.

Einführung

Addierst du 1 zu einem Zeiger, rückt er nicht um 1 Byte vor, sondern zum nächsten Element des Arrays, weil der Compiler die Schrittweite anhand der Typgröße berechnet. So kannst du mit Zeigern einen zusammenhängenden Speicherbereich wie ein Array durchlaufen.

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 values[] = {10, 20, 30, 40};
    int sum = 0;
    for (int *p = values; p < values + 4; ++p) sum += *p;
    printf("sum=%d distance=%td\n", sum, (values + 4) - values);
    return 0;
}
Ergebnis der Ausführung
sum=100 distance=4
C++
Code ausführen →
main.cpp
#include <iostream>
#include <vector>

int main() {
    std::vector values{10, 20, 30, 40};
    int sum = 0;
    for (auto it = values.begin(); it != values.end(); ++it) sum += *it;
    std::cout << "sum=" << sum << " distance="
              << std::distance(values.begin(), values.end()) << '\n';
}
Ergebnis der Ausführung
sum=100 distance=4

C und C++ im Vergleich

Die Schleife beginnt mit dem Zeiger p auf dem ersten Element und rückt vor, bis p die Position values + 4 erreicht. In jedem Schritt holt *p den aktuellen Wert und addiert ihn zur Summe. Zeigerarithmetik ist nur innerhalb desselben Arrays oder direkt hinter seinem letzten Element gültig. In C++ ermöglichen Iteratoren, viele verschiedene Container auf dieselbe Weise zu durchlaufen.

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