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 4Address 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 ./progStack 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=yeslokalisiert 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
- Warum Valgrind
- Leaks erkennen
- Ungültiger Speicherzugriff
- Berichte lesen