0Pricing
C Academy · Lektion

Ungültiger Speicherzugriff

Zugriffe außerhalb von Grenzen und nicht initialisierte Daten

Ungültiger Speicherzugriff ist eine kostenlose C Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C Academy-Kurs umfasst insgesamt 4 Lektionen.

Über Speicherlecks hinaus

Lecks verschwenden Speicher, aber Fehler durch ungültige Zugriffe beschädigen ihn. memcheck erkennt mehrere Arten:

  • Lesen oder Schreiben über das Ende eines Puffers hinaus
  • Verwenden von Speicher nach free
  • Lesen nicht initialisierter Werte
  • Lesen oder Schreiben über einen ungültigen Zeiger

Diese Fehler verursachen die gefährlichsten und am schwersten reproduzierbaren Abstürze.

Schreiben außerhalb der Grenzen

Hier wird Platz für 5 int-Werte reserviert, aber auf Index 5 — den sechsten Eintrag — geschrieben.

Index 5 liegt ein Element hinter dem Ende. memcheck meldet an dieser Zeile ein Invalid write of size 4.

#include <stdlib.h>

int main(void) {
    int *a = malloc(5 * sizeof(int));
    a[5] = 99; /* valid indices are 0..4 */
    free(a);
    return 0;
}

Die Fehlermeldung lesen

Der Bericht nennt den Vorgang, die Größe und die Position relativ zum Block:

Invalid write of size 4
Address 0x... is 0 bytes after a block of size 20 alloc'd

„0 bytes after a block of size 20“ bedeutet, dass der Zugriff direkt hinter einer 20 Byte großen Allokation (5 int-Werte) erfolgt ist.

Lesen außerhalb der Grenzen

Auch Lesezugriffe werden erkannt. Hier läuft die Schleife ein Element zu weit.

memcheck markiert in der letzten Iteration ein Invalid read of size 4, obwohl das Programm zufällig scheinbar „funktionieren“ kann.

#include <stdlib.h>
#include <stdio.h>

int main(void) {
    int *a = calloc(3, sizeof(int));
    for (int i = 0; i <= 3; i++)   /* should be i < 3 */
        printf("%d\n", a[i]);
    free(a);
    return 0;
}

Nicht initialisierte Werte

malloc setzt den Speicher nicht auf null. Wenn Sie ihn verwenden, bevor Sie ihm einen Wert zuweisen, entsteht ein unvorhersehbarer Wert.

memcheck meldet Conditional jump or move depends on uninitialised value(s), wenn ein solcher Wert den Kontrollfluss oder die Ausgabe beeinflusst.

#include <stdlib.h>
#include <stdio.h>

int main(void) {
    int *p = malloc(sizeof(int));
    if (*p == 0)              /* *p was never set */
        printf("zero\n");
    free(p);
    return 0;
}

Warum Meldungen zu nicht initialisierten Werten später erscheinen

memcheck meldet nicht sofort, wenn Sie nicht initialisierten Speicher lesen. Es verfolgt, ob Werte „definiert“ sind, und meldet einen Fehler erst, wenn ein undefinierter Wert tatsächlich relevant wird, etwa in einer Verzweigung, Ausgabe oder einem Systemaufruf.

So werden Fehlalarme vermieden, wenn Sie nicht initialisierte Bytes harmlos kopieren.

Verwendung nach der Freigabe

Der Zugriff auf Speicher nach dessen Freigabe ist undefiniertes Verhalten. memcheck erkennt dies präzise.

Es meldet Invalid read of size 4 mit dem Hinweis Address ... is 0 bytes inside a block of size 4 free'd und zeigt sogar, wo das free erfolgt ist.

#include <stdlib.h>
#include <stdio.h>

int main(void) {
    int *p = malloc(sizeof(int));
    *p = 7;
    free(p);
    printf("%d\n", *p);   /* read after free */
    return 0;
}

Doppelte Freigabe

Das zweimalige Freigeben desselben Zeigers beschädigt die Verwaltungsdaten des Allokators.

memcheck meldet Invalid free() und zeigt sowohl die aktuelle Freigabe als auch die ursprüngliche Allokation an, sodass der Fehler offensichtlich wird.

#include <stdlib.h>

int main(void) {
    int *p = malloc(sizeof(int));
    free(p);
    free(p);   /* freed twice */
    return 0;
}

Ursprünge nachverfolgen

Fügen Sie bei Fehlern mit nicht initialisierten Werten --track-origins=yes hinzu.

memcheck meldet dann, wo der fehlerhafte Wert erstellt wurde, nicht nur, wo er verwendet wurde. So wird aus einer vagen Warnung eine präzise Fehlerbehebung.

valgrind --track-origins=yes ./prog

Stack und globale Variablen

memcheck ist besonders gut bei Fehlern im Heap. Bei Überläufen auf dem Stack oder in globalen Arrays ist seine Abdeckung schwächer.

In solchen Fällen ist AddressSanitizer (gcc -fsanitize=address) oft die bessere Wahl. Die beiden Werkzeuge ergänzen sich.

Off-by-one: Der Nullterminator

Ein häufiger Heap-Überlauf entsteht, wenn der Stringterminator vergessen wird. strlen gibt für 'hello' den Wert 5 zurück, aber der String benötigt 6 Byte, um das abschließende '\0' zu speichern.

memcheck meldet einen Invalid write, wenn strcpy dieses letzte Byte hinter das Ende schreibt.

#include <stdlib.h>
#include <string.h>

int main(void) {
    char *s = malloc(strlen("hello")); /* needs +1 */
    strcpy(s, "hello");                 /* writes the '\0' past end */
    free(s);
    return 0;
}

Schnelltest

Ermitteln Sie, was memcheck für das Codefragment meldet.

Zusammenfassung

Sie können jetzt Fehler bei ungültigen Speicherzugriffen erkennen:

  • Zugriffe außerhalb von Grenzen werden als Invalid read/write mit dem Block-Offset angezeigt
  • Nicht initialisierte Werte werden gemeldet, sobald sie eine Entscheidung oder Ausgabe beeinflussen
  • Use-after-free und doppelte Freigaben werden einschließlich beider Aufrufstellen erkannt
  • --track-origins=yes lokalisiert undefinierte Werte; kombinieren Sie es bei Stack-Fehlern mit ASan

Als Nächstes: den vollständigen Bericht lesen.

Häufig gestellte Fragen

Ist die Lektion „Ungültiger Speicherzugriff“ kostenlos?

Ja — der vollständige Text von „Ungültiger Speicherzugriff“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Ungültiger Speicherzugriff“?

Zugriffe außerhalb von Grenzen und nicht initialisierte Daten Du übst C Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um C Academy zu starten?

Keine Vorkenntnisse erforderlich. C Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Ungültiger Speicherzugriff“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser C Academy-Lektion Code schreiben und ausführen?

Ja. Jede C Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Warum Valgrind
  2. Leaks erkennen
  3. Ungültiger Speicherzugriff
  4. Berichte lesen
← Zurück zu C Academy