[Powered by Google Translate] [Valgrind] [Nate Hardison, Harvardin yliopisto] Tämä on CS50, CS50.TV] Jotkut vaikeimmista bugeja C ohjelmissa tulevat huonosta muistista. On olemassa valtava määrä tapoja ruuvi asioita, lukien jakaminen väärän muistin määrä unohtamatta alustaa muuttujat, kirjallisesti ennen tai sen jälkeen loppuun puskuria, ja vapauttaa pitää muistissa useita kertoja. Oireet vaihtelevat kaatumiset ja salaperäisesti päälle arvoja, usein paikoissa ja aikoina kaukana alkuperäisestä virhe. Jäljitys havaittu ongelma takaisin taustalla syynä voi olla haastavaa, mutta onneksi siellä on hyödyllinen ohjelma nimeltä Valgrind jotka voivat tehdä paljon auttaakseen. Voit suorittaa ohjelman nojalla Valgrind jotta laaja tarkastaminen kasan muistin jakaminen ja vierailuja. Kun Valgrind havaitsee ongelman, se antaa sinulle välittömästi, suoraa tietoa, jonka avulla voit helpommin löytää ja korjata ongelman. Valgrind myös raportit vähemmän tappava muistiongelmia, kuten muistivuotoja, jakaminen keon muistia, ja unohtaa sen vapauttamiseksi. Kuten meidän kääntäjä, clang, meidän debuggeri, GDB, Valgrind on ilmainen ohjelmisto, ja se on asennettu laitteeseen. Valgrind toimii teidän suoritettavassa, ei sinun. c tai. h lähdekooditiedostoihin, joten varmista, että olet koonnut ajan tasalla kopion ohjelmasta käyttäen clang tai Make. Sitten, suorittaa ohjelma alle Valgrind voidaan niin yksinkertainen kuin vain edeltävällä vakio ohjelman komento sana Valgrind, joka käynnistyy Valgrind ja käynnistää ohjelman sisälle. Kun aloitat, Valgrind ei monimutkaisia jiggering määrittää suoritettavan varten muistin tarkastuksia, joten se voi kestää hieman päästä vauhtiin. Ohjelma sitten suorittaa normaalisti, on se paljon hitaammin, ja kun se päättyy, Valgrind tulostaa yhteenvedon sen muistin käyttöä. Jos kaikki menee hyvin, se näyttää tältä: Tässä tapauksessa. / Clean_program on polku ohjelmaan haluan ajaa. Ja vaikka tämä ei ole mitään perusteluja, jos se ei olisin vain tack ne loppuun komennon normaalisti. Clean-ohjelma on vain typerä pieni ohjelma Loin joka jakaa tilaa lohko ints kasaan, laittaa arvot itseensä, ja vapauttaa koko korttelin. Tämä on mitä kuvaat varten, ei virheitä eikä vuotoja. Toinen tärkeä metriikka on tavujen kokonaismäärä jaetaan. Riippuen ohjelmasta, jos määrärahat ovat megatavuina tai uudempi, olet luultavasti jotain väärin. Oletko turhaan varastointiin kaksoiskappaleet? Käytätkö kasan varastointiin, jolloin se olisi parempi käyttää pino? Joten, muisti virheitä voi olla todella paha. Avoimempi niistä aiheuttaa näyttäviä kaatumisia, mutta silloinkin se voi silti olla vaikea paikantaa mitä johti kaatua. Enemmän salakavalasti, ohjelman muistin virhe voi vielä koota siististi ja voi silti tunnu toimivan oikein koska olet onnistunut saamaan onnekas suurimman osan ajasta. Kun useita "onnistuneita tuloksia" saatat ajatella, että onnettomuudessa on onnenpotku tietokoneen, mutta tietokone ei ole koskaan väärässä. Juoksu Valgrind avulla voit jäljittää syy näkyvän muistinloppumisvirheitä sekä löytää väijyvä virheitä et edes vielä tiedä. Aina Valgrind havaitsee ongelman, se tulostaa tiedot siitä, mitä havaitaan. Jokainen tuote on melko niukkasanainen - lähde linja rikkoneen opetusta, mikä ongelma on, ja vähän tietoa muistin mukana - mutta usein se on tarpeeksi tietoa ohjata huomiota oikeaan paikkaan. Tässä on esimerkki Valgrind käynnissä viallisista ohjelman että ei kelpaa lukea kasan muistia. Emme näe mitään virheitä tai varoituksia kokoelma. Uh-oh, virhe yhteenvedon mukaan on olemassa kaksi virhettä - kaksi virheellinen luettu joiden koko oli 4 - tavua, että on. Molemmat huono lukee tapahtunut päätehtävä invalid_read.c, ensimmäisellä rivillä 16 ja toisella rivillä 19. Katsotaanpa koodi. Näyttää ensimmäisen puhelun printf yrittää lukea yksi int ohi lopussa meidän muisti estää. Jos katsomme taaksepäin Valgrind tuotokseen, näemme, että Valgrind kertoi meille juuri sitä. Osoite yritämme lukea käynnistyy 0 tavua pään ohi lohkon koko 16 tavua - neljään 32-bittinen ints että me myönnetty. Eli osoite yritimme lukea alkaa aivan lopussa meidän lohkon, kuten näemme huono printf puhelun. Nyt kelpaa luettu ei ehkä kuulosta kovin iso juttu, mutta jos käytät että tietoja virtausta ohjelma - esimerkiksi osana jos ilmoitus tai silmukka - Sitten asiat voivat äänettömästi mennä huonosti. Katso, miten voin ajaa invalid_read ohjelma eikä mitään tavallisuudesta tapahtuu. Pelottava, eikö? Nyt, katsotaanpa hieman erilaisia ​​virheitä, joita saattaa esiintyä koodissa, ja näemme kuinka Valgrind tunnistaa ne. Näimme esimerkin invalid_read, joten nyt mennään tarkistaa invalid_write. Jälleen, ei virheitä tai varoituksia kokoelma. Okei, Valgrind sanoo, että on olemassa kaksi virhettä tässä ohjelmassa - ja invalid_write ja invalid_read. Katsotaanpa tarkistaa tätä koodia. Näyttää meillä esiintymän klassinen strlen plus yksi bugi. Koodi ei malloc ylimääräistä tavun tilaa varten / 0 luonnetta, joten kun str kopio meni kirjoittamaan sitä ssubstrlen "cs50 rocks!" se kirjoitti 1 tavu ohi lopussa meidän lohko. Invalid_read tulee, kun teemme puhelun printf. Printf päätyy lukemalla kelpaa muistia, kun se lukee / 0 hahmo koska se näyttää lopussa tämän E-kieli on tulostuksen. Mutta mikään tästä pakeni Valgrind. Näemme, että pyydetty invalid_write osana str kopion rivillä 11 tärkeimpien ja invalid_read on osa printf. Rock, Valgrind. Jälleen kerran, tämä ei ehkä tunnu iso juttu. Voimme ajaa ohjelman uudestaan ​​ja uudestaan ​​ulkopuolella Valgrind eikä näe mitään virhettä oireita. Kuitenkin Katsotaanpa hieman vaihtelua tämän nähdä miten asiat voidaan saada todella huono. Joten, myönnetään, olemme väärin asioita enemmän kuin vain hieman tätä koodia. Olemme vain jakaa tilaa kasaan kaksi jousille pituus cs50 kiviä, tällä kertaa, muistaa / 0 luonnetta. Mutta sitten heittää erittäin pitkä merkkijono muistilohkoon että S on osoittaa. Mitä vaikutuksia tällä on muistin lohko, T viittaa? No, jos T viittaa muistia on vain vieressä S- tulossa vain sen jälkeen, Sitten olisimme kirjoittaneet yli osan T. Katsotaanpa suorittaa tämän koodin. Katsokaa mitä tapahtui. Strings me varastoituu kasaan korttelin molemmat näytti tulostaa oikein. Mikään ei näytä väärin ollenkaan. Kuitenkin, mennään takaisin meidän koodi ja kommentti, rivi, jossa me kopioida cs50 kiviä toiseen muistiin lohko, viittasi t. Nyt, kun otamme tämän koodin meidän pitäisi vain nähdä sisällön ensimmäisen muistilohkon tulostaa. Hei, vaikka emme str kopiota merkkejä toiseen kasaan lohko, joka huomautti T, saamme tulostaa. Itse merkkijono me tungetaan ensimmäinen lohko levisivät ensimmäinen lohko ja toiseen lohkoon, tekee kaiken näyttämään normaalia. Valgrind kuitenkin kertoo tositapahtumiin. Siellä mennään. Kaikki nämä virheellinen lukee ja kirjoittaa. Katsotaanpa esimerkki toisenlaisen virheen. Täällä teemme jotakin melko ikävää. Me napata tilaa int kasaan, ja me alustaa int osoitin - p - osoittamaan, että tilaa. Kuitenkin, kun taas meidän osoitin on alustettu, tiedot, että se on suunnattu vain on mitä roskaa on, että osa kasaan. Joten kun lataat että dataa int i, Olemme teknisesti alustaa i, mutta teemme niin roskaa tietoihin. Puhelun puolustamaan, joka on kätevä virheenkorjaus makro määritelty osuvasti nimetty väittävät kirjasto, tulee keskeyttää ohjelman, jos sen testiolosuhteissa epäonnistuu. Toisin sanoen, jos i ei ole 0. Riippuen siitä, mitä oli kasaan avaruudessa, huomautti P, tämä ohjelma voisi toimia joskus ja epäonnistua muina aikoina. Jos se toimii, me vain saada onnekas. Kääntäjä ei kiinni tämän virheen, mutta Valgrind varma tahtoa. Siellä näemme virhe johtuvat käytämme tätä roskaa tietoja. Kun jakaa keon muistia, mutta älä deallocate sitä tai vapauttaa sen, että kutsutaan vuoto. Pienelle, lyhytaikainen ohjelma, joka toimii ja heti ulos, vuodot ovat melko harmittomia, mutta hankkeen suuremman koon ja / tai pitkäikäisyyttä, pienikin vuoto voi pahentaa osaksi jotain suurta. Sillä CS50 Emme odota teidän huolehtia vapauttaa kaikki keon muistin että voit jakaa, koska haluamme rakentaa taitoja kunnolla käsittelemään manuaalisia edellyttämät C. Voit tehdä ohjelma olisi tarkka yksi-yhteen vastaavuus välillä malloc ja ilmaiset puhelut. Onneksi Valgrind voi auttaa sinua muistivuotoja liikaa. Tässä on vuotava ohjelma nimeltä leak.c joka jakaa tilaa kasaan, kirjoittaa siihen, mutta ei vapauttaa sen. Laadimme sitä Merkki ja suorita sille Valgrind, ja näemme, että vaikka meillä ei ole muistia virheitä, meillä on yksi vuoto. On 16 tavua menettänyt lopullisesti, siten, että osoitin, että muisti ei ole laajuudeltaan, kun ohjelma poistutaan. Nyt, Valgrind ei anna meille ton tietoa vuotaa, mutta jos noudatamme tätä pikku merkille, että se antaa pohjaa vasten sen raportin ja uusintana kanssa - vuoto-check = täysin nähdä täydelliset tiedot vuotanut muistia, saamme enemmän tietoa. Nyt kasaan yhteenveto, Valgrind kertoo jos muistia hävisi alunperin jaettu. Aivan kuten tiedämme katsomalla lähdekoodia, Valgrind kertoo meille, että me vuotanut muistia kohdennetaan puhelun malloc rivillä 8 leak.c in päätehtävä. Aika näppärä. Valgrind luokittelee vuodot näillä hakusanoilla: Ehdottomasti menetetty - tämä on kasa jaettu muisti jolle ohjelma ei enää ole osoitinta. Valgrind tietää, että olet kerran ollut osoitin, mutta on sittemmin kadottaa sen. Tämä muisti on varmasti vuotanut. Välillisesti menetetty - tämä on kasa jaettu muisti johon ainoastaan ​​osoittimia se myös menetetään. Esimerkiksi, jos olet menettänyt osoitin ensimmäiseen solmuun linkitetty lista, Sitten ensimmäinen solmu itse olisi varmasti menetetty, taas myöhemmin solmuja olisi epäsuorasti menetetty. Mahdollisesti menetetty - tämä on kasa jaettu muisti jonka Valgrind ei voi olla varma, onko osoitin tai ei. Edelleen tavoitettavissa on kasa jaettu muisti jonka ohjelma on vielä osoitin exit mikä yleensä tarkoittaa, että globaali muuttuja osoittaa sen. Voit tarkistaa nämä vuodot, sinun on myös sisällytettävä mahdollisuus - Yhä tavoitettavissa = kyllä oman vetoaminen Valgrind. Nämä eri tapaukset saattavat vaatia erilaisia ​​strategioita puhdistamiseen niitä, mutta vuodot olisi poistettava. Valitettavasti vahvistamisesta vuodot voi olla vaikea tehdä, koska väärä puhelut ilmaiseksi voi räjäyttää ohjelman. Esimerkiksi, jos katsomme invalid_free.c, näemme esimerkki huonosta muistista deallocation. Mikä olisi yksittäinen puhelu vapauttaa koko korttelin muistin huomautti by int_block, on sen sijaan tullut yritys vapauttaa jokaisen INT-kokoinen kappale ja muistin erikseen. Tämä epäonnistuu katastrofaalisesti. Boom! Mikä virhe. Tämä ei todellakaan ole hyvä. Jos olet juuttunut tällaista virhettä, vaikka, ja et tiedä mistä etsiä, pudota takaisin uusi paras ystävä. Arvasit oikein - Valgrind. Valgrind, kuten aina, tietää tarkalleen, mitä on tekeillä. Alloc ja vapaa määrä eivät täsmää. Meillä 1 alloc ja 4 Frees. Ja Valgrind myös kertoo meille, missä ensimmäinen huono free-puhelun - joka laukaisi räjähdys - on lähtöisin - linja 16. Kuten näette, huono puhelut vapauttaa ovat todella huonoja, niin suosittelemme kerroit ohjelma vuoto kun olet työskennellyt saamaan toiminnallisuus oikea. Alkaa etsiä vuotoja vasta sen jälkeen, kun ohjelma toimii oikein, ilman muita virheitä. Ja se on kaikki mitä minulla tämän videon. Nyt mitä sinä odotat? Mene ajaa Valgrind sinun ohjelmia juuri nyt. Nimeni on Nate Hardison. Tämä on CS50. [CS50.TV]