Wycieki pamięci
Wykrywanie i unikanie wycieków
Wycieki pamięci to bezpłatna lekcja C Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C Academy zawiera 4 lekcji w sumie.
Czym jest wyciek pamięci
Wyciek pamięci występuje, gdy zaalokujesz pamięć na stercie, ale nigdy jej nie zwolnisz i utracisz jedyny wskaźnik do niej.
Pamięć pozostaje zarezerwowana aż do zakończenia programu, powodując marnowanie zasobów.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
*p = 5;
printf("%d\n", *p);
free(p);
return 0;
}Utrata wskaźnika
Klasyczny wyciek polega na nadpisaniu wskaźnika nową alokacją przed zwolnieniem starej.
Pierwszy blok staje się nieosiągalny.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
free(p);
p = malloc(sizeof(int));
*p = 10;
printf("%d\n", *p);
free(p);
return 0;
}Wycieki w pętlach
Alokowanie pamięci wewnątrz pętli bez zwalniania jej w każdej iteracji szybko zwielokrotnia wyciek.
Rozwiązaniem jest zwolnienie pamięci przed kolejną iteracją, która nadpisze wskaźnik.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
for (int i = 0; i < 3; i++) {
int *p = malloc(sizeof(int));
*p = i;
printf("%d ", *p);
free(p);
}
printf("\n");
return 0;
}Wczesne return powoduje wyciek
Wczesne return po alokacji może pominąć sprzątanie. Zawsze zwalniaj pamięć na każdej ścieżce wyjścia.
#include <stdio.h>
#include <stdlib.h>
int process(int bad) {
int *p = malloc(sizeof(int));
if (bad) {
free(p);
return -1;
}
*p = 42;
int r = *p;
free(p);
return r;
}
int main(void) {
printf("%d\n", process(0));
return 0;
}Schemat sprzątania z goto
Pojedyncza etykieta sprzątania, do której prowadzi goto, zapewnia jedno miejsce zwalniające całą pamięć i pozwala uniknąć powielania wywołań free.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int rc = 1;
int *p = malloc(sizeof(int));
if (!p) goto done;
*p = 7;
printf("%d\n", *p);
rc = 0;
done:
free(p);
return rc;
}Dopasuj zwolnienie do każdej alokacji
Najprostsza zasada: każdemu wywołaniu malloc, calloc lub realloc musi odpowiadać dokładnie jedno wywołanie free.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *a = malloc(8);
char *b = calloc(4, sizeof(char));
a[0] = 'x';
printf("%c %d\n", a[0], b[0]);
free(a);
free(b);
return 0;
}Zwalnianie zagnieżdżonych alokacji
Jeśli struktura zarządza pamięcią na stercie, zwolnij wewnętrzne wskaźniki przed zwolnieniem zewnętrznego bloku.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int *data;
} Box;
int main(void) {
Box *b = malloc(sizeof(Box));
b->data = malloc(3 * sizeof(int));
b->data[0] = 1;
printf("%d\n", b->data[0]);
free(b->data);
free(b);
return 0;
}Zwalnianie tablicy wskaźników
Gdy alokujesz tablicę wskaźników, a każdy element jest osobną alokacją, najpierw zwolnij każdy element, a dopiero potem tablicę.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n = 3;
int **rows = malloc(n * sizeof(int *));
for (int i = 0; i < n; i++) {
rows[i] = malloc(2 * sizeof(int));
rows[i][0] = i;
}
for (int i = 0; i < n; i++) free(rows[i]);
free(rows);
printf("freed all rows\n");
return 0;
}Zasady własności
Ustal, kto posiada każdą alokację i odpowiada za jej zwolnienie. Udokumentuj to, aby osoby wywołujące funkcję wiedziały, czy muszą zwolnić zwrócony wskaźnik.
#include <stdio.h>
#include <stdlib.h>
char *make_greeting(void) {
char *s = malloc(6);
s[0]='h'; s[1]='i'; s[2]='\0';
return s;
}
int main(void) {
char *g = make_greeting();
printf("%s\n", g);
free(g);
return 0;
}Narzędzia wykrywające wycieki
Narzędzia takie jak Valgrind i AddressSanitizer wykrywają wycieki, śledząc każdą alokację i wskazując te, które nigdy nie zostały zwolnione.
Są niezbędne do weryfikowania rzeczywistych programów.
Cykl życia poprawnej alokacji
Podsumowując: alokuj pamięć, sprawdzaj wynik, używaj jej, zwalniaj na każdej ścieżce i wyzeruj wskaźnik. Dzięki temu programy pozostają wolne od wycieków.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(4 * sizeof(int));
if (!p) return 1;
for (int i = 0; i < 4; i++) p[i] = i + 1;
int sum = 0;
for (int i = 0; i < 4; i++) sum += p[i];
printf("sum = %d\n", sum);
free(p);
p = NULL;
return 0;
}Szybkie sprawdzenie
Sprawdź swoje zrozumienie wycieków pamięci.
Podsumowanie
Dowiedziałeś się, jak zapobiegać wyciekom pamięci:
- Każdą alokację dopasuj do dokładnie jednego wywołania
free. - Zwalniaj pamięć na każdej ścieżce wyjścia, także przy wczesnych zwrotach i błędach.
- Zwalniaj zagnieżdżone alokacje oraz alokacje tablic wskaźników, zaczynając od elementów wewnętrznych.
- Jasno określaj własność pamięci i używaj narzędzi takich jak Valgrind do weryfikacji.
Często zadawane pytania
Czy lekcja „Wycieki pamięci” jest bezpłatna?
Tak — pełny tekst „Wycieki pamięci” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C Academy, przejdź na CoddyKit PRO. Kurs C Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Wycieki pamięci”?
Wykrywanie i unikanie wycieków Ćwiczysz C Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C Academy?
Nie wymagamy żadnego doświadczenia. C Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Wycieki pamięci”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C Academy?
Tak. Każda lekcja C Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- malloc i free
- calloc i realloc
- Wycieki pamięci
- Wiszące wskaźniki