Vuotojen havaitseminen
memcheckin perusteet.
Vuotojen havaitseminen on ilmainen C Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C Academy-kurssilla on yhteensä 4 oppituntia.
Mikä vuoto on
Muistivuoto syntyy, kun varaat kekomuistia funktiolla malloc, calloc tai realloc ja menetät kaikki siihen osoittavat osoittimet ennen free-funktion kutsumista.
Lohko pysyy varattuna mutta saavuttamattomana prosessin päättymiseen asti. Pitkään suoritettavissa ohjelmissa vuodot kasaantuvat, kunnes muisti loppuu.
Pienin mahdollinen vuoto
Tämä ohjelma vuotaa yhden 40 tavun lohkon.
Osoitin p on paikallinen muuttuja. Kun main palaa, p katoaa, mutta sen osoittamaa kekomuistilohkoa ei koskaan vapauteta.
#include <stdlib.h>
int main(void) {
int *p = malloc(10 * sizeof(int));
p[0] = 1;
return 0; /* never free(p) */
}memcheckin suorittaminen
memcheck on oletustyökalu, joten työkalun nimen voi jättää pois.
Lisää --leak-check=full, niin saat pinon jäljityksen jokaisesta vuotaneesta varauksesta.
gcc -g -O0 -o leak leak.c
valgrind --leak-check=full ./leakVuotoyhteenveto
Valgrind tulostaa ohjelman päättyessä LEAK SUMMARY -yhteenvedon. Edellä mainitusta ohjelmasta se näyttää suunnilleen tältä:
definitely lost: 40 bytes in 1 blocks
Jäljitys osoittaa täsmälliseen malloc-kutsukohtaan, joten tiedät tarkalleen, mitä varausta ei vapautettu.
Neljä vuotokategoriaa
memcheck luokittelee kadonneen muistin neljään ryhmään:
- definitely lost — yhtään osoitinta ei ole jäljellä; kyseessä on todellinen vuoto
- indirectly lost — saavutettavissa vain definitely lost -lohkon kautta
- possibly lost — jäljellä on vain osoitin lohkon sisälle
- still reachable — osoitin on olemassa ohjelman päättyessä, mutta et koskaan vapauttanut lohkoa
Definitely lost ja still reachable
definitely lost on kiireellisin kategoria: näitä tavuja ei voi palauttaa ohjelman suorituksen aikana.
still reachable on lievempi tapaus. Lohko on vuotanut ohjelman päättyessä, mutta globaali tai staattinen osoitin viittaa siihen edelleen. Kyseessä on yleensä kertaluonteinen varaus, jota ei yksinkertaisesti ole muistettu vapauttaa.
Epäsuorat vuodot
Kun linkitetyn rakenteen alkuosoitin katoaa, jokaisesta solmusta tulee saavuttamaton.
Alkuosoitin näkyy luokassa definitely lost ja loput solmut luokassa indirectly lost. Kun korjaat perimmäisen syyn eli kadonneen alkuosoittimen, kaikki muisti saadaan palautettua.
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 */Korjattu versio
Vapauta kaikki, minkä varaat. Tämä versio ei vuoda muistia.
Valgrind raportoi siitä 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;
}Varausten laskeminen
HEAP SUMMARY -yhteenveto kertoo myös ilman vuotoja, kuinka paljon ohjelmasi käytti muistia:
total heap usage: 1 allocs, 1 frees, 40 bytes allocated
Kun varausten ja vapautusten määrät täsmäävät, suoritus on puhdas. Ero määrissä on ensimmäinen vihje siitä, että jotain pääsi katoamaan.
Saavutettavissa olevien lohkojen näyttäminen
Oletuksena memcheck ei luettele still reachable -lohkoja yksityiskohtaisesti. Tarkasta myös ne lisäämällä:
--show-leak-kinds=all
Tämä pakottaa jäljityksen jokaiselle kategorialle. Se on hyödyllistä, kun haluat ohjelman vapauttavan kaiken muistin ennen päättymistä.
valgrind --leak-check=full --show-leak-kinds=all ./leakVirhepolkujen muistivuodot
Salakavalimmat vuodot piilevät ennenaikaisen paluun poluissa. Tässä tapauksessa ensimmäinen lohko vuotaa, jos toinen varaus epäonnistuu.
Tavallinen testaus osuu harvoin näihin haaroihin, mutta memcheck havaitsee vuodot aina, kun polku suoritetaan. Vapauta aina hallussasi oleva muisti ennen virheen yhteydessä palaamista.
char *a = malloc(100);
char *b = malloc(100);
if (!b) {
/* bug: a is leaked here */
return -1;
}
/* fix: free(a); before returning */Pikatesti
Valitse vuotokategoria, joka vaatii kiireellisintä huomiota.
Kertaus
Nyt osaat havaita muistivuodot memcheckillä:
- Suorita
valgrind --leak-check=full ./prog-g-valitsimella käännetylle binäärille - Lue LEAK SUMMARY- ja HEAP SUMMARY -yhteenvedot
- Priorisoi definitely lost -tapaukset ja selvitä sitten epäsuorat vuodot niiden juurisyyhyn asti
- Käytä
--show-leak-kinds=all-valitsinta tarkastaaksesi edelleen saavutettavissa olevat lohkot
Seuraavaksi: virheelliset muistinkäytöt.
Opi C tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 39
- Oppitunnit
- 144
Usein kysytyt kysymykset
Onko oppitunti ”Vuotojen havaitseminen” ilmainen?
Kyllä – oppitunnin ”Vuotojen havaitseminen” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C Academy-kurssin, päivitä CoddyKit PROhon. C Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Vuotojen havaitseminen”?
memcheckin perusteet. Harjoittelet C Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni C Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin C Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”Vuotojen havaitseminen”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä C Academy-oppitunnilla?
Kyllä. Jokainen C Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Miksi Valgrind
- Vuotojen havaitseminen
- Virheellinen käyttö
- Raporttien lukeminen