C Academy · Lektion

Leaks erkennen

Grundlagen von memcheck

Lektion 2 von 413 Schritte

Leaks erkennen ist eine kostenlose C Academy-Lektion auf CoddyKit. Dies ist Lektion 2 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.

Was ein Speicherleck ist

Ein Speicherleck entsteht, wenn Sie mit malloc, calloc oder realloc Speicher im Heap reservieren und jeden Zeiger darauf verlieren, bevor Sie free aufrufen.

Der Block bleibt reserviert, ist aber bis zum Beenden des Prozesses nicht erreichbar. In dauerhaft laufenden Programmen summieren sich Lecks, bis der Speicher erschöpft ist.

Ein minimales Speicherleck

Dieses Programm verliert einen Speicherblock von 40 Byte.

Der Zeiger p ist eine lokale Variable. Wenn main zurückkehrt, verschwindet p, aber der Heap-Block, auf den er gezeigt hat, wird nie freigegeben.

#include <stdlib.h>

int main(void) {
    int *p = malloc(10 * sizeof(int));
    p[0] = 1;
    return 0; /* never free(p) */
}

memcheck ausführen

memcheck ist das Standard-Tool, daher können Sie den Tool-Namen weglassen.

Fügen Sie --leak-check=full hinzu, um für jede verlorene Allokation einen Stacktrace zu erhalten.

gcc -g -O0 -o leak leak.c
valgrind --leak-check=full ./leak

Die Leckzusammenfassung

Beim Beenden gibt Valgrind eine LEAK SUMMARY aus. Für das obige Programm lautet sie ungefähr:

definitely lost: 40 bytes in 1 blocks

Der Trace verweist auf die genaue Stelle des malloc-Aufrufs, sodass Sie genau wissen, welche Allokation nie freigegeben wurde.

Die vier Le Kategorien

memcheck teilt verlorenen Speicher in vier Kategorien ein:

  • definitely lost — kein Zeiger ist mehr vorhanden; ein echtes Leck
  • indirectly lost — nur über einen definitiv verlorenen Block erreichbar
  • possibly lost — nur ein Zeiger ins Innere des Blocks ist noch vorhanden
  • still reachable — beim Beenden existiert noch ein Zeiger, aber Sie haben den Speicher nie freigegeben

Definitiv verloren vs. noch erreichbar

definitely lost ist die dringende Kategorie: Diese Bytes können während der Laufzeit des Programms nicht mehr zurückgewonnen werden.

still reachable ist weniger kritisch. Der Block ist beim Beenden zwar nicht freigegeben, wird aber noch von einem globalen oder statischen Zeiger referenziert. Daher handelt es sich meistens um eine einmalige Allokation, deren Freigabe Sie schlicht nicht vorgesehen haben.

Indirekte Lecks

Wenn Sie den Anfang einer verketteten Struktur verlieren, wird jeder Knoten unerreichbar.

Der Anfang wird als definitely lost und der Rest als indirectly lost angezeigt. Wenn Sie die Ursache — den verlorenen Anfang — beheben, wird der gesamte Speicher wieder freigegeben.

struct Node { int v; struct Node *next; };

struct Node *make(void) {
    struct Node *h = malloc(sizeof *h);
    h->next = malloc(sizeof *h);
    h->next->next = NULL;
    return h;
}
/* if the caller drops the returned head, both nodes leak */

Die korrigierte Version

Geben Sie frei, was Sie reservieren. Diese Version weist keine Lecks auf.

Unter Valgrind meldet sie All heap blocks were freed -- no leaks are possible.

#include <stdlib.h>

int main(void) {
    int *p = malloc(10 * sizeof(int));
    p[0] = 1;
    free(p);
    return 0;
}

Allokationen zählen

Auch ohne Lecks zeigt die HEAP SUMMARY, wie stark Ihr Programm ausgelastet war:

total heap usage: 1 allocs, 1 frees, 40 bytes allocated

Wenn die Anzahl der Allokationen und Freigaben übereinstimmt, war der Lauf sauber. Eine Abweichung ist der erste Hinweis darauf, dass etwas nicht freigegeben wurde.

Erreichbare Blöcke anzeigen

Standardmäßig listet memcheck still reachable-Blöcke nicht im Detail auf. Um auch diese zu prüfen, fügen Sie Folgendes hinzu:

--show-leak-kinds=all

Dadurch wird für jede Kategorie ein Trace ausgegeben. Das ist nützlich, wenn Ihr Programm vor dem Beenden wirklich alles freigeben soll.

valgrind --leak-check=full --show-leak-kinds=all ./leak

Lecks auf Fehlerpfaden

Die am schwersten zu entdeckenden Lecks verbergen sich in Pfaden mit vorzeitiger Rückgabe. Wenn hier die zweite Allokation fehlschlägt, bleibt der erste Block belegt.

Bei gewöhnlichen Tests werden diese Verzweigungen nur selten ausgeführt, aber memcheck findet die Lecks jedes Mal, wenn der Pfad durchlaufen wird. Geben Sie vor einer Rückgabe wegen eines Fehlers immer alles frei, was Sie noch besitzen.

char *a = malloc(100);
char *b = malloc(100);
if (!b) {
    /* bug: a is leaked here */
    return -1;
}
/* fix: free(a); before returning */

Kurze Überprüfung

Wählen Sie die Leckkategorie aus, die am dringendsten behandelt werden muss.

Zusammenfassung

Sie können nun Lecks mit memcheck erkennen:

  • Führen Sie valgrind --leak-check=full ./prog mit einer -g-Binärdatei aus
  • Lesen Sie die LEAK SUMMARY und die HEAP SUMMARY
  • Priorisieren Sie definitely lost und verfolgen Sie anschließend indirekte Lecks bis zu ihrer Ursache zurück
  • Verwenden Sie --show-leak-kinds=all, um noch erreichbare Blöcke zu prüfen

Als Nächstes: ungültige Speicherzugriffe.

Kostenlos starten

Lerne C mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
39
Lektionen
144

Häufig gestellte Fragen

Ist die Lektion „Leaks erkennen“ kostenlos?

Ja — der vollständige Text von „Leaks erkennen“ 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 „Leaks erkennen“?

Grundlagen von memcheck 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 2 von 4.

Wie lange dauert die Lektion „Leaks erkennen“?

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