Wykrywanie wycieków
Podstawy memcheck
Wykrywanie wycieków to bezpłatna lekcja C Academy na CoddyKit. To lekcja 2 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
Wyciek pamięci występuje, gdy zaalokuje Pan / zaalokuje Pani pamięć sterty za pomocą malloc, calloc lub realloc, a następnie utraci wszystkie wskaźniki do niej przed wywołaniem free.
Blok pozostaje zarezerwowany, ale niedostępny aż do zakończenia procesu. W długo działających programach wycieki kumulują się, aż zabraknie pamięci.
Minimalny wyciek
Ten program powoduje wyciek jednego bloku o rozmiarze 40 bajtów.
Wskaźnik p jest zmienną lokalną. Gdy main zwróci sterowanie, p znika, ale wskazywany przez niego blok sterty nigdy nie zostaje zwolniony.
#include <stdlib.h>
int main(void) {
int *p = malloc(10 * sizeof(int));
p[0] = 1;
return 0; /* never free(p) */
}Uruchamianie memcheck
memcheck jest narzędziem domyślnym, więc można pominąć nazwę narzędzia.
Dodaj --leak-check=full, aby uzyskać ślad stosu dla każdej wyciekającej alokacji.
gcc -g -O0 -o leak leak.c
valgrind --leak-check=full ./leakPodsumowanie wycieków
Przy zakończeniu Valgrind wyświetla podsumowanie LEAK SUMMARY. Dla powyższego programu wygląda ono mniej więcej tak:
definitely lost: 40 bytes in 1 blocks
Ślad wskazuje dokładne miejsce wywołania malloc, dzięki czemu wiadomo, która alokacja nie została zwolniona.
Cztery kategorie wycieków
memcheck dzieli utraconą pamięć na cztery kategorie:
- definitely lost — nie pozostał żaden wskaźnik; rzeczywisty wyciek
- indirectly lost — dostępna wyłącznie przez blok oznaczony jako definitely lost
- possibly lost — pozostał tylko wskaźnik wewnętrzny
- still reachable — przy zakończeniu istnieje wskaźnik, ale pamięć nie została zwolniona
Definitely lost a still reachable
definitely lost to kategoria wymagająca pilnej uwagi: tych bajtów nie można odzyskać podczas działania programu.
still reachable jest łagodniejszą kategorią. Blok jest wyciekiem przy zakończeniu programu, ale nadal wskazuje na niego wskaźnik globalny lub statyczny, więc zwykle chodzi o jednorazową alokację, której po prostu nie zwolniono.
Wycieki pośrednie
Gdy utraci się początek połączonej struktury, każdy węzeł staje się niedostępny.
Początek jest oznaczany jako definitely lost, a pozostałe elementy jako indirectly lost. Usunięcie przyczyny źródłowej, czyli utraconego początku, odzyskuje całą pamięć.
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 */Wersja poprawiona
Zwalniaj wszystko, co alokujesz. Ta wersja nie powoduje żadnych wycieków.
Uruchomiona pod kontrolą Valgrind zgłasza 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;
}Zliczanie alokacji
Nawet przy braku wycieków podsumowanie HEAP SUMMARY informuje, jak intensywnie program korzystał z pamięci:
total heap usage: 1 allocs, 1 frees, 40 bytes allocated
Gdy liczba alokacji i zwolnień się zgadza, uruchomienie przebiegło poprawnie. Niezgodność to pierwsza wskazówka, że coś nie zostało zwolnione.
Wyświetlanie dostępnych bloków
Domyślnie memcheck nie wyświetla szczegółowej listy bloków still reachable. Aby sprawdzić także je, dodaj:
--show-leak-kinds=all
Wymusza to ślad dla każdej kategorii i jest przydatne, gdy program ma zwalniać absolutnie wszystko przed zakończeniem.
valgrind --leak-check=full --show-leak-kinds=all ./leakWycieki na ścieżkach błędów
Najbardziej podstępne wycieki kryją się na ścieżkach z wcześniejszym powrotem. W tym przypadku, jeśli druga alokacja się nie powiedzie, pierwszy blok wycieknie.
Zwykłe testy rzadko wykonują te gałęzie, ale memcheck wykrywa takie wycieki, gdy tylko dana ścieżka zostanie wykonana. Przed powrotem z obsługi błędu zawsze zwalniaj posiadaną pamięć.
char *a = malloc(100);
char *b = malloc(100);
if (!b) {
/* bug: a is leaked here */
return -1;
}
/* fix: free(a); before returning */Szybki test
Wybierz kategorię wycieku, która wymaga najpilniejszej uwagi.
Podsumowanie
Potrafi Pan już / Potrafi już Pani wykrywać wycieki za pomocą memcheck:
- Uruchom
valgrind --leak-check=full ./progna pliku binarnym skompilowanym z opcją-g - Przeczytaj LEAK SUMMARY i HEAP SUMMARY
- Najpierw zajmij się kategorią definitely lost, a następnie prześledź wycieki pośrednie do ich źródła
- Użyj
--show-leak-kinds=all, aby sprawdzić bloki still reachable
Następny temat: nieprawidłowy dostęp do pamięci.
Często zadawane pytania
Czy lekcja „Wykrywanie wycieków” jest bezpłatna?
Tak — pełny tekst „Wykrywanie wycieków” 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 „Wykrywanie wycieków”?
Podstawy memcheck Ć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 2 z 4.
Ile czasu zajmuje lekcja „Wykrywanie wycieków”?
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
- Dlaczego Valgrind
- Wykrywanie wycieków
- Nieprawidłowy dostęp
- Odczytywanie raportów