[Musikk spilles]
>> DAVID J. MALAN: All right.
Dette er CS50.
Og dette er starten på uke fem.
Og som du kanskje har lagt merke til, noe av materialet
blir litt mer kompleks, den lille tettere.
>> Og det er veldig lett, spesielt hvis du har hatt for vane i noen tid,
å være å prøve å rable ned det meste alt vi gjør, vi sier i klassen.
Men skjønner, det er ikke kanskje den ideelle pedagogisk tilnærming
til å lære denne typen materiale, og materialet mer generelt.
Og så vi er glade for å kunngjøre at CS50 egen Gheng
Gong har begynt å forberede en kanonisk sett av notater
for kurset, håpet som er at, en, disse
ikke bare tjene som en referanse og en ressurs
for gjennomgang av materiale og går tilbake gjennom materialet som kan ha
rømte du i første omgang, men også slik at hodet kan være mer
opp enn i bakken, da det gjelder tid til å forelese,
slik at du kan engasjere seg mer gjennomtenkt, som
motsetning til mer Scribbly.
>> Med det sagt, hva du finner på nettstedet er slike dokumenter som dette.
Og legg merke til, øverst til venstre, er det ikke bare en innholdsfortegnelse,
men også tid koder som vil umiddelbart hoppe deg
til den aktuelle delen i video på nettet.
Og hva Chang her har gjort er, i hovedsak, dokumentert
hva som skjedde i dette bestemt forelesning.
Og mange av forelesningene er allerede online nå med denne nettadressen.
Og vi vil fortsette å legge ut resten av dem innen utgangen av denne uken,
så dra nytte av den ressursen.
>> Så uten videre, vi begynte å skrelle tilbake
det laget som har vært strengen i noen tid.
Og hva gjorde vi si en streng faktisk er i forrige uke?
Så røye stjerne.
Og røye stjerne, vel, hva gjorde det egentlig betyr?
Vel, hele denne tiden, hvis vi har vært ringer en funksjon,
som getString og lagring den såkalte retur
Verdien av getString i en variable-- det heter
s typen string-- vi har skrevet kodelinjen oppe ovenfor.
Og det er bare når jeg ser min håndskrift forstørret her
jeg innser hvor fryktelig dette er.
>> Men la oss anta at, på høyre side
er, likevel, en rimelig skildring av hva som er
pågått alt dette tid med getString.
getString naturligvis får en streng.
Men hva betyr det egentlig?
Det betyr at det blir en del av minne fra operativsystemet
ved å kalle en funksjon, kalt malloc.
Men mer om det senere.
Og da er det fylles som del av minne
med bokstavene brukeren har skrevet inn, etterfulgt av, selvsagt
en null karakter, eller omvendt skråstrek null helt på slutten.
>> I mellomtiden, på den venstre side i denne historien, hele denne tiden,
vi har vært å erklære en variabel, som s.
Og at variabelen er det nå vil begynne å ringe en peker.
Det er ikke en boks innsiden av som vi sette strengen, Daven, per se,
men heller vi satt i denne firkanten feltet til venstre for hva?
Yeah?
>> PUBLIKUM: Adressen der den ligger i minnet.
>> DAVID J. MALAN: Nettopp.
Adressen der Daven er plassert i minnet.
Og ikke hvor alle av Daven ligger, per se, men spesielt adresse
av hva?
Yeah?
>> PUBLIKUM: Første tegn.
>> DAVID J. MALAN: Det første tegnet i Daven, som i dette tilfellet,
Jeg foreslo var vilkårlig og urealistisk 1, OX1,
som bare menes heksadesimale nummer 1.
Men det er trolig kommer å være en mye større tall
at vi kan trekke med en 0x som prefiks,
representerer en heksadesimale tegn.
Og fordi vi ikke trenger å vite hvor resten av tegnene på Daven
er, på grunn av det enkle utforming beslutning som ble gjort for mange år siden?
Yeah?
>> PUBLIKUM: Omvendt skråstrek 0.
DAVID J. MALAN: Ja, akkurat.
Backslash 0 kan du, om enn i lineær tid, for å traversere streng,
gange fra venstre til høyre, med en for løkke, eller en stund
loop, eller noe sånt det, og bestemme, oh, her
er enden av denne strengen.
Så med bare den adressen begynnelsen av en streng,
vi kan få tilgang til helheten av det, fordi alt dette samtidig,
en streng har nettopp vært en char stjerne.
>> Så det er sikkert greit å fortsette å bruke den CS50 biblioteket og denne abstraksjon,
så å si, men vi vil begynne å se nøyaktig
hva som har skjedd på under hele denne tiden.
Så du husker kanskje dette eksemplet også, fra sist gang, sammenligne 0,
som ikke egentlig sammenligne.
Men vi begynte å løse dette.
>> Men som kanskje en oppfriskning, kan jeg interessere noen
i en rosa elefant i dag, også laget av Chang?
Hva med deg foran? [Uhørbart].
Kom opp.
>> Og i mellomtiden, når du kommer opp, la oss
vurdere for bare et øyeblikk hva denne koden ble faktisk gjør.
Det erklærte to variabler opp toppen, s og t, og ringer getString.
Dette er ikke en svært brukervennlig program fordi den ikke forteller deg hva du skal gjøre.
Men la oss bare anta vi er fokus på den saftige delen.
Og så vi gjør, hvis s lik er lik t, bør det si printf,
du skrev det samme.
Hei.
Hva heter du?
>> JANELLE: Janelle.
DAVID J. MALAN: Janelle, hyggelig å møte deg.
Så din utfordring på hånden for denne elefant
er først å trekke oss et bilde av hva som er å være representert i de to første
linjer.
Så s og t kan være representert hvor på skjermen?
Og du kan bare trekke den med fingeren på dette store skjermen.
>> Så det er to halvdelene til hver side av ligningen.
Så det er s til venstre, og deretter getString til høyre.
Og så er det t til venstre, og deretter getString til høyre.
Så hvordan kan vi begynne tegne et bilde som
representerer hva som skjer her i minnet, vil du si?
Og la meg fortelle deg forklare hva du gjør når du går.
>> JANELLE: OK.
Vel, først, det ville være å spørre du å få input strengen.
Og det ville store-- oh, sorry.
DAVID J. MALAN: OK.
Good.
Og dette kalles hva?
Oh, OK.
Holde det gående.
Jeg mente ikke å avbryte.
JANELLE: Beklager.
Så det ville innspill den inn adressen of-- ikke sikker.
Jeg kan ikke akkurat huske nummeret, men jeg tror det var begynt med 0.
>> DAVID J. MALAN: Det er greit, fordi jeg gjorde tallene opp,
så det er ingen riktig svar.
>> JANELLE: Fra og med 0 bue.
>> DAVID J. MALAN: OK, så element 0.
Sure.
>> JANELLE: Og så hvis var som bare en to-letter--
>> DAVID J. MALAN: OK, tilbake til deg.
>> JANELLE: Så element 0, og deretter element 1 eller element 2..
DAVID J. MALAN: Og hvilken del av bildet er du tegne akkurat nå?
Kallet til getString?
Eller erklæringen av s?
>> JANELLE: Erklæringen av s, tror jeg.
Oh, den getString, fordi det ville legges inn i hver [? området. ?]
>> DAVID J. MALAN: Good.
Nettopp.
Selv om dette effektivt returnerer en matrise, husker,
når vi kommer tilbake en streng, kan vi indeks inn i strengen ved hjelp av 01 og 2.
Teknisk sett er dette trolig representert av private adresser,
men det er fint.
>> Så antar, hvis jeg bare kan fort frem til der vi slapp
siste tid, hvis en av strengene var g a b e,
backslash 0, og dermed representerer Gabes input, hvordan kan vi representerer s nå?
Hvis dette er minne som er blitt returnert av getString?
>> JANELLE: Ville det være representert ved en bue?
>> DAVID J. MALAN: Ved en bue?
Vel, nei.
La oss bare si, billedlig, la meg bare gå videre
og foreslår at, dersom dette er s, denne er returverdien av getString.
Og du har tegnet dette som 0, 1, 2, som er helt rimelig, fordi vi
kan indeksere inn i strengen, som sådan.
Men bare for å være i samsvar med siste gang, la meg gå videre
og vilkårlig foreslå at dette er adresse 1, dette er adresse 2,
dette er adressen 3, og så videre.
Og så, bare for å være super klart, hva skjer
å gå i s som et resultat av at første linje med kode, vil du si?
>> JANELLE: Adresse 1?
>> DAVID J. MALAN: Nettopp.
Så ta 0x1.
Og i mellomtiden, la meg gå videre og duplisere mye av det du har gjort
og legge til min egen t her.
Hvis jeg skulle skrive inn Gabe igjen, en andre gang,
når du blir bedt med getString, hvor, selvfølgelig er Gabe kommer til å gå?
Vel, presumably--
>> JANELLE: Som på her?
DAVID J. MALAN: Yeah.
JANELLE: Eller det er også i de samme boksene?
DAVID J. MALAN: La meg foreslå, ja, nøyaktig, så i disse ekstra bokser.
Men hva er nøkkelen nå er at selv om jeg har trukket disse ganske nær
together-- 0x1, dette er 0x2-- i virkeligheten,
dette nå kan være adresse 0x10, for eksempel, og 0x11 og 0x12,
og så videre.
Og så, hvis det er tilfelle, hva som kommer til å ende opp her i t?
>> JANELLE: 0x10?
DAVID J. MALAN: Nettopp.
Så 0x10.
Og så nå, siste spørsmål.
Du har langt, måtte jobbe hardest for en elefant så langt.
Nå, hvis jeg trekker opp koden igjen, når jeg gjør det, på linje tre,
hvis s lik lik t, hva er jeg faktisk sammenligne det vi har tegnet her?
>> JANELLE: De to adresser?
DAVID J. MALAN: Nettopp.
Så jeg sier er S lik lik t?
Med andre ord, er en tilsvarende lik 10?
Og selvfølgelig, åpenbare svaret er nå, nei.
Og så dette programmet er slutt kommer til å skrive ut det, ville du si?
>> JANELLE: Ville det være, du skrev det samme?
>> DAVID J. MALAN: Så hvis s er 1, og t er 10?
>> JANELLE: Du skrev forskjellige ting.
>> DAVID J. MALAN: Nettopp.
Du skrev forskjellige ting.
Greit.
Så en runde med applaus, hvis vi kunne, her.
[APPLAUSE]
Det var smertefullt.
Jeg vet.
Pent gjort.
Så nå la oss se om vi ikke kan erte hverandre hva reparasjonen var.
Og selvfølgelig, når vi fikset dette-- som jeg skal nå representere i green--
vi gjorde et par forbedringer her.
Først, akkurat som en mental helse sjekk, jeg først å sjekke
hvis s er lik null og t er lik null.
Og bare for å være klar, når kanskje s eller t være null i kode som dette?
Når kan s eller t være null.
Yeah?
>> PUBLIKUM: [uhørlig].
>> DAVID J. MALAN: Nettopp.
Hvis strengen som brukeren skrevet i er altfor lang
til å passe inn i minnet, eller noen rare hjørne tilfelle sånn,
getString, så vi får se, bokstavelig talt i dag, i sin dokumentasjon,
sier det vil returnere null som en spesiell sentinel verdi,
eller bare liksom et spesielt symbol det betyr at noe gikk galt.
Så vi ønsker å se etter at, fordi det viser seg
at null er en svært farlig verdi.
>> Ofte, hvis du prøver å gjøre noe med null involverer en function-- passerer det
som input, for instance-- at funksjonen kan meget vil krasje, og med det,
ta ned hele programmet.
Så denne tredje linjen er nå bare en mental helse sjekk, feilkontroll, hvis du vil.
Det er en god vane nå for oss å komme inn hver gang vi
prøver å bruke en verdi som kan potensielt være null.
>> Nå, i den fjerde linje her, "Hvis strcmp (s, t)," vel,
hva er det å henvise til?
Vel, sa vi at dette var en veldig konsist oppkalt funksjon for streng sammenligning.
Og dens formål i livet er å sammenligne sitt første argument mot det andre,
men ikke i form av deres adresser, som vi gjorde utilsiktet et øyeblikk
siden med den røde kode, men heller å sammenligne disse to
strenger i menneskelig intuitive måte ved å sammenligne dette mot dette,
mot dette, mot dette, og så stopper hvis og når en
eller begge av fingrene treffer en backslash 0.
Så noen år siden gjennomført strcmp å gjennomføre for oss funksjonaliteten
at vi håpet vi ville ha fått bare ved å sammenligne to enkle verdier.
>> Nå ærlig, jeg holder tegning alle disse ulike tall.
Men realiteten er, jeg har vært noe som gjør disse opp hele tiden.
Og så la meg bare gå videre og smøre disse ut
å gjøre et punkt som, ved slutten av dagen og fremover,
vi egentlig ikke kommer til å bry seg om hva løser ting er faktisk
i minnet.
Så jeg har ikke tenkt å trekke disse typer tall så mye lenger,
Jeg er bare en abstrakt dette bort en litt mer vennlig med bare piler.
>> Med andre ord, hvis s er en peker, vel, la oss bare tegne det, bokstavelig talt,
som en peker, en pil som peker fra seg selv til noe annet,
og ikke bekymre deg for mye mer om minutia av disse adressene
som, igjen, gjorde jeg opp likevel.
Men vi får se disse adressene, noen ganger, når debugging kode.
>> Nå i mellomtiden, dette programmet opp her fikser, selvfølgelig,
at problemet ved å sammenligne de to strenger.
Men vi kjørte inn i et annet problem.
Dette var fra kopien programmere siste gang,
der, var jeg prøver å kapital bare det første tegn i en streng.
Men det var symptomet vi så forrige gang når
en bruker har skrevet inn en verdi, som Gabe med små bokstaver, for s,
da vi tildelt s til t, som i den tredje linje der,
og da jeg prøvde å kapitalisere t brakett 0?
Det var effekten av skiftende t brakett 0 her?
>> PUBLIKUM: Det endret s.
>> DAVID J. MALAN: Yeah, I forandret s, samt.
Fordi hva som egentlig skjer?
Vel, la meg se om jeg kan rydde opp dette bildet, som følger.
>> Hvis s er, igjen, ordet g, a, b, e, skråstrek, 0 og s
vi vil fortsette med tegningen som en boks Hit men ikke flere adresser.
La oss slutte å gjøre ting opp.
La oss bare tegne et bilde å forenkle hele verden.
>> Når jeg erklærer t med hyssing t, som skaper som del av minnet.
Square skjer for å være 32 biter i de fleste datamaskiner.
Faktisk, hvis du noen gang hørt om en datamaskin med en 32-bits arkitektur,
virkelig fancy-tale, som bare betyr at det bruker 32-bits adresser.
Og som en teknisk side, hvis du noen gang har lurt
hvorfor eldre datamaskiner, hvis du faktisk prøvde å suppe dem opp med masse RAM,
bare kunne ha en maksimal av fire gigabyte RAM,
vel det er fordi, bokstavelig talt, den gamle datamaskinen kunne bare
teller så høyt som 4 milliarder kroner, 4 milliarder bytes,
fordi det var ved hjelp av 32-bit tall for adresser.
>> Men i alle fall i denne eksempel historien er mye enklere.
t er bare en annen pekeren, eller virkelig en char stjerne, aka streng.
Og hvordan gjør jeg vil oppdatere dette bildet nå med at andre linje med kode,
etter dot, dot, dot?
Når jeg gjør strengen t tilsvarer s semikolon, hvordan endre dette bildet?
Yeah?
>> PUBLIKUM: [uhørlig].
>> DAVID J. MALAN: Yeah.
Nettopp.
Jeg bare sette en pil fra t boksen til den samme adresse,
det samme første bokstaven i ga.
Eller teknisk sett, hvis dette fyren var fortsatt på 0x1,
det er som om jeg hadde 0x1 her og 0x1 her.
Men igjen, hvem bryr seg om adresser?
Det er bare tanken som nå teller.
Så dette er hva som skjer her.
Så selvfølgelig, hvis du gjør t brakett 0, som er array notasjon,
av course-- og ærlig, ser det som om det er en rekke over her,
men nå er det denne rare ting.
Vet at programmeringsspråket, C, og tilbyr denne funksjonen,
hvorved, selv om t er et pekeren, eller s er en peker,
du kan fortsatt bruke den velkjente, komfortabel hakeparentes
notasjon for å gå til det første elementet, eller det andre elementet, eller en hvilken som helst element
at det pilen peker til grunn, antagelig, det
er, som i dette tilfellet peke på noen array.
>> Så hvordan løser vi dette?
Oppriktig, dette er hvor den fikk en litt overveldende ved første øyekast.
Men her er en ny og forbedret versjon.
>> Så først, jeg får kvitt CS50 biblioteket,
bare for å avsløre at S er faktisk en char stjerne, bare et synonym.
Og t er også en røye stjerne.
Men hva som skjer på høyre side av denne linjen
hvor t er programmert med en verdi?
>> Hva er malloc?
Hva det er strlen?
Hva er sizeof (char)?
Hvorfor i all verden gjør dette Online ser så komplisert?
Hva er det du gjør på et høyt nivå?
Hva er det lagring i t?
Yeah?
PUBLIKUM: Det er tildeling av en viss mengde plass i minnet.
Det er å lagre, antar jeg, bokstaver [uhørbart].
>> DAVID J. MALAN: Perfect.
Perfect.
Det er tildeling av en viss Mengden av minne
å lagre, formodentlig, fremtidige bokstaver.
Og i særdeleshet, malloc derfor tilbake hva?
>> PUBLIKUM: Retur [uhørbart]?
DAVID J. MALAN: Nettopp.
Returnere adressen til minne, som er en fancy måte å si:
returnerer adressen til første byte av dette minnet.
Den tyngende på meg å huske hvor mye minne jeg faktisk
tildelt eller bedt malloc for.
>> Nå hvor mye er det?
Vel, selv om det er mange parenteser her,
malloc tar bare ett argument.
Og jeg spesifisere strlen av s, så gi meg så mange bytes som det er i s,
men legg til en.
Hvorfor?
Yeah?
>> PUBLIKUM: The backslash 0.
DAVID J. MALAN: Nettopp.
Vi er nødt til å gjøre en liten rengjøring.
Så fordi det er en skråstrek 0, ville vi bedre huske det.
Ellers skal vi for å lage en streng som
har ikke den spesielle terminator.
>> I mellomtiden, bare for å være super anal, har jeg sizeof (char),
bare i tilfelle noen kjører min koden ikke på CS50 apparatet,
men kanskje en annen datamaskin tilsammen der chars
er en byte, etter konvensjonen, men to bytes, eller noe større enn det.
Det er bare å være super, super uvillig til feil.
Selv om, i virkeligheten er det mest sannsynlig kommer til å være en 1.
>> Nå, i mellomtiden, jeg gå videre og kopiere streng, t brakett jeg lik t brakett s.
Og jeg vil utsette til siste ukes kildekoden for å se hva som skjer.
Men nøkkelen takeaway, og grunnen til at jeg setter inn koden nå i grønt,
er fordi det aller siste linje, t brakett 0 tilsvarer toupper,
har den virkning aktivere denne som streng?
t og / eller s?
Det siste kodelinje.
>> Bare t, fordi det er skjedde denne gangen,
hvis jeg angrer litt på at siste trinnet, hva som har skjedd er, når jeg kaller malloc,
Jeg egentlig få en del av minne som er samme størrelse som originalen,
fordi det er den aritmetiske jeg gjorde.
Jeg lagring i t adressen av at del av minnet.
Selv om dette ser fint og pen, fin og blank,
realiteten er det er, hva vi vil holde ringer, søppel verdier her.
Som del av minnet kan meget godt ha vært brukt før,
noen sekunder, noen få minutter siden.
Så det kan absolutt være tall eller bokstaver der, bare ved et uhell.
Men de er ikke gyldig, før jeg meg selv fylle denne del av minne
med faktiske tegn, som jeg gjøre ved at for sløyfe der.
Greit?
>> Så nå klimaks disse tre eksempler
som ble tilsynelatende brutt forrige gang, dette Swap eksempel denne funksjonen
arbeidet i den forstand at det byttet a og b.
Men det fungerte ikke i hva andre forstand?
Yeah?
>> PUBLIKUM: [uhørlig].
>> DAVID J. MALAN: Nettopp.
Hvis jeg skulle kalle denne funksjonen fra another-- f.eks
fra en funksjon som hoved, der Jeg har en variabel, x og y, som jeg
gjorde i forrige uke, samme koden, og jeg passere i x og y
til Bytt, og deretter ringe Swap-- dette, selvfølgelig, er den korrekte versjonen
er hva vi er i ferd med å see-- det ikke fungerte.
Så hva er den fix?
>> Vel, så bare for å være klar, la meg gå videre
og-- gi meg ett sekund her, og se hvis jeg kan vise deg den siste, som
vil være i-- la oss se om jeg kan finne dette ekte fast-- OK, [uhørbart].
OK, er det.
Så ignorere kommandoene jeg bare skrive.
Jeg vil at det skal hente om siste øyeblikk et eksempel
fra forrige gang, som heter nå ingen Swap.
>> Så ingen Swap er der vi slapp forrige gang,
der, initialisert jeg x og y til 1 til 2.
Jeg deretter ringe Swap, passerer i 1 og 2.
Og så denne funksjonen jobbet i en viss forstand,
men det hadde ingen permanent bevirke on x og y.
Så spørsmålet på hånden er, hvordan nå gjør vi faktisk fikse dette problemet?
Det er løsningen på hånden?
>> Vel, i swap.c, som er nytt i dag, legge merke til et par forskjeller.
x og y er de samme.
Men hva er klart annerledes med linje 25?
Hva er nytt der, hvis du husker hvordan det så ut en andre siden?
>> PUBLIKUM: [uhørlig].
>> DAVID J. MALAN: Yeah.
Så-tegn er en ny brikke syntaks, ikke bare i dette programmet,
men også mer generelt i CS50.
Til dags dato tror jeg ikke vi har sett noen eksempler
eller egentlig snakket om dem på noen detalj, annet enn, kanskje, preemptively
i snitt, et ampersand som dette.
Vel, det viser seg ampersand er en av de siste bitene av ny syntaks
vi kommer til å lære.
Alt det betyr er Adressen noen variabel.
På hvilken adresse lever x?
Men hva adressen lever y?
Fordi hvis den grunnleggende problem før
ble det x og y ble passert som kopier, hva vi virkelig ønsker å gjøre
er gi Swap med som en skatt kart som fører til der x og y faktisk
er i RAM, slik at Swap kan følge det kartet
og gå dit x eller y markerer stedet og endre de faktiske verdiene 1 og 2
der.
>> Så Swap må endres litt også.
Og ved første øyekast, kan dette virke litt lik røye stjerne.
Og faktisk er det.
Så en er en peker til hva slags data, basert på denne uthevede delen?
Så det er en int.
>> Slik at en ikke lenger er en int, det er adressen til en int.
Og tilsvarende, er b nå skal å være adressen til en int.
Så når jeg nå kaller Swap fra Main, Jeg har ikke tenkt å gi Swap 1 og 2.
Jeg kommer til å gi det som Ox-noe og Ox-noe,
to adresser som vil føre Bytt til deres faktiske steder
i datamaskinens minne.
>> Så nå, min gjenværende implementering må endres en smule.
Hva er åpenbart annerledes nå i disse tre linjer med kode?
Det er disse jævla stjerner alle over alt, ok?
Så hva er det som skjer her?
Yeah?
>> PUBLIKUM: Det er tydeligvis [uhørbart].
>> DAVID J. MALAN: Nettopp.
Så i denne context-- og dette var ikke den beste designen avgjørelse, riktignok,
år siden.
I denne sammenheng, hvor du bare har en stjerne,
og du ikke har en datatype, som int, umiddelbart til venstre,
i stedet du har et likhetstegn, tydelig, i denne sammenheng, når du sier stjerners A,
det betyr gå til adresse som er i en.
Følg kartet skatten, så å si.
>> Og i mellomtiden, i tråd 37, det betyr det samme.
Gå til adressen en, og legge det der?
Uansett er på plassering som b angir.
Med andre ord, gå til b.
Få denne verdien.
Gå til en og, per likhets signere, oppdraget operatør,
sette denne verdien der.
>> Tilsvarende er int temp bare en int.
Ingenting må endres om temp.
Det er bare et ekstra glass fra Annenberg for melk eller appelsinsaft.
Men jeg trenger å si, gå til b.
Gå til denne destinasjonen og sette verdien i temp der.
Så hva skjer da?
Når jeg faktisk ringe Swap denne gangen, hvis denne første skuffen her representerer Main,
denne andre brett representerer Swap, når Jeg passerer Ampersand x og ampersand y
fra Main til Bytt, bare for å være klar, hva er dette stabel ramme mottak?
Yeah?
>> PUBLIKUM: [uhørlig].
DAVID J. MALAN: Nettopp.
Adressen for x og adressen y.
Og du kan tenke på disse som postadresser.
33 Oxford Street og 35 Oxford Street, og du
ønsker å flytte de to bygningene som finnes på disse steder.
>> Det er liksom en latterlig idé, men det er alt vi mener med adresse.
Hvor i verden kan du finner disse to ints?
Hvor i verden kan du finne disse to bygningene?
Så hvis endelig, etter all denne tiden jeg gå inn i dagens kildekoden og kompilere
Swap og kjøre ./swap, til slutt, for den første gang vi faktisk se at
mine verdier har faktisk blitt byttet vellykket.
Og nå kan vi selv ta oppmerksom på dette i for eksempel gdb.
>> Så la meg gå inn i samme fil.
La meg gå videre og kjøre gdb av ./swap.
Og nå, i Swap, jeg kommer til å gå foran og sette en pause punkt i Main.
Og nå kommer jeg til å gå videre og kjøre programmet.
Og nå ser vi min kode pauset på den linjen.
>> Hvis jeg går videre og print x, hva bør jeg se her?
Det er et spørsmål.
Si igjen?
>> PUBLIKUM: [uhørlig].
>> DAVID J. MALAN: Så tilfeldige tall, kanskje.
Kanskje jeg er heldig, og det er fin og enkel, som 0.
Men kanskje det er noen tilfeldige tall.
I dette tilfellet fikk jeg heldig.
Det skjer bare for å være 0.
Men det er faktisk flaks, fordi ikke før jeg
skriv neste, og deretter skrive ut x har som kodelinje, linje 19, blitt henrettet.
>> I mellomtiden, hvis jeg skriver neste gang, og nå skrive ut y, jeg kommer til å se 2.
Nå, hvis jeg skriver neste, kommer det til å bli litt forvirrende, fordi nå,
printf kommer til å vises på skjermen, som det gjorde. x er 1.
>> La oss gjøre dette igjen.
Og nå, her hvor ting blir interessant.
Før jeg kaller Swap eller trinn inn i det, la oss ta en liten titt.
x er, igjen, 1.
Y er, selvfølgelig, hurtig normalitet kontrollere, 2, slik at det ikke vanskelig.
Men hva er tegnet x?
Svar, er det slags funky utseende.
Men int stjerne i parentes er bare BNP måte å si dette er en adresse.
Det er ikke en int, er det en peker til en int, eller ellers kjent som en adresse.
>> Hva er dette sprø ting?
Vi har aldri sett noe ganske sånn før.
Så dette er adressen i datamaskinens minne om hvor x tilfeldigvis lever.
Det er Ox-noe.
Og dette er oppriktig, hvorfor Jeg har begynt å tegne piler,
i stedet for tall, fordi som virkelig bryr seg
at int er på et bestemt adresse som er så stor.
Men bffff0c4, disse er alle faktisk heksadesimale siffer,
som er 0 til f.
>> Så vi ikke kommer til å dvele for lenge på hva disse tingene er.
Men hvis jeg skriver ut y, selvfølgelig, ser jeg to.
Men ampersand y, ser jeg denne adressen.
Og legg merke til, for de nysgjerrige, hvor langt fra hverandre er x og y?
Du kan ignorere det meste av adressen.
Fire byte.
Og det er i tråd med vår tidligere hevder at hvor stor er en int?
Fire byte.
Så det ser ut som alt er lining opp pent, som du kanskje håper, i minnet.
>> Så nå, la oss bare spole frem til slutten av denne historien.
La oss gå videre og skriv skritt, å dykke inn i Swap-funksjonen.
Nå legger merke til, hvis jeg skriver en, er det identisk med adressen til x.
Hvis jeg skriver b, er det identisk til adressen y.
Så hva skal jeg se om jeg si, gå til adressen en?
Så ut stjerners en.
Så stjerne betyr gå dit, i denne sammenheng.
Ampersand mener det er adressen.
Så stjerners et middel en.
Og print stjerners b gir meg to.
>> Og la meg anta, for øyeblikket, at i det minste den kode som
fortsetter å kjøre nå kan være begrunnet gjennom på den måten.
Men vi vil se denne ideen før lenge.
Så denne versjonen av Swap er nå riktig og lar
oss til å bytte denne datatypen.
>> Så noen spørsmål deretter på Swap?
På stjerne?
På adressen?
Og du vil se, med Problemet satt fire, liksom,
men problemet satt fem, definitivt, hvordan disse ting er nyttige og få mye mer
komfortabel med dem, som et resultat.
Noe som helst?
Greit.
Så malloc er, igjen, denne funksjonen som bare tildeler minne, minne
tildeling.
Og hvorfor er dette nyttig?
Vel, hele denne tiden, du har brukt malloc.
Hvis du vurderer nå hvordan getString verk, antagelig er det
vært stille noen for en del av minne, når som helst brukeren skriver en streng
i, fordi vi absolutt ikke visste, som CS50 ansatte,
hvor store disse strengene som mennesker kommer til å skrive kan være.
>> Så la oss, for første gang, begynner å Vipp hvordan CS50 bibliotek fungerer,
ved hjelp av et par eksempler som vil føre oss dit.
Så hvis jeg åpner opp gedit og åpne opp scanf 0,
vi kommer til å se følgende kode.
Scanf 0, som er tilgjengelig på nettsiden for i dag, har relativt få linjer med kode
her, 14 gjennom 20.
Og la oss se hva det gjør.
Det erklærer en int, kalt x.
Det sier noe sånt, antall takk.
Og nå sier det, scanf% i, og x.
Så det er en haug med nye ting der.
>> Men scanf, kan du slags tror av som det motsatte av printf.
printf, selvfølgelig, utskrifter til skjermen.
scanf slags skanner fra brukerens tastaturet noe han eller hun har skrevet.
>> % I er akkurat som printf.
Dette betyr forvente at brukeren å skrive en int.
Og nå, hvorfor tror du jeg kanskje passerer scanf & x?
Hvis hensikten i livet av scanf er å få noe fra brukeren,
hva er meningen med passerer den, og x, nå?
Yeah?
>> PUBLIKUM: [uhørlig].
DAVID J. MALAN: Nettopp.
Uansett hva jeg, det menneskelige, skriv inn, mitt innspill kommer til å bli frelst på den plasseringen.
Det er ikke tilstrekkelig, husker, å bare passere i x, fordi vi har sett allerede,
hver gang du passerer bare en rå variabel, som en int, til en annen funksjon,
sikker, kan det endre det variabel, men ikke permanent.
Det kan ikke ha en effekt på Main.
Det kan bare endre sin egen lokale kopi.
Men hvis, i stedet, trenger du ikke gi meg den faktiske int,
men du gir meg veibeskrivelse til som int, jeg nå, blir scanf,
sikkert, kan jeg følge at adresse og sette et tall der
slik at du har tilgang til det også.
>> Så når jeg kjører dette programmet, la oss se.
Gjør scanf 0 dot slash, scanf 0.
Og hvis jeg nå skriver inn et tall som 50, takk for den 50.
Hvis jeg nå skriver inn et tall som negative 1, for den negative 1.
Jeg nå skriver inn et tall som 1.5, hm.
Hvorfor gjorde mitt program ignorere meg?
Vel, fordi rett og slett, jeg fortalte det å forvente bare en int.
Greit.
Så det er en versjon av dette.
La oss ta ting opp et hakk og foreslå at dette ikke er bra.
Og her ligger et veldig enkelt eksempel av hvordan vi kan begynne å skrive kode
at andre mennesker kan utnytte eller kompromiss ved å gjøre dårlige ting.
Så linje 16, så like i ånden til før,
men jeg er ikke erklære det int denne gangen.
Jeg erklære det røye stjerne, aka streng.
>> Men hva betyr det egentlig?
Så hvis jeg ikke spesifiserer en address-- og Jeg kaller det tilfeldig, buffer,
men jeg kan kalle det s, for å være simple-- og så gjør jeg dette, forklare meg,
hvis du kunne, basert på den forrige logikk, hva er scanf gjør i linje 18,
hvis pass% s og buffer, som er en adresse?
Hva er scanf, hvis du bruker det nøyaktig samme logikk som versjon 0,
skal prøve å gjøre her, når brukeren skriver noe i?
Yeah?
>> PUBLIKUM: [uhørlig].
>> DAVID J. MALAN: Nettopp.
Scanf, av logikken tidligere kommer til å ta strengen
at den menneskelige maskinskrevet i-- det er nå en streng,
det er ikke et tall, formodentlig, hvis han eller hun cooperates--
og det kommer til å prøve å sette det string i minnet på uansett adresse
buffer angir.
Og dette er flott, fordi buffer faktisk er ment å være en adresse.
>> Men jeg hevder dette programmet er buggy i en svært alvorlig måte, fordi hva verdien er
buffer som standard?
Hva har jeg initialisert inn?
Hva mengde minne?
Jeg har ikke, ikke sant?
>> Så selv om jeg har tildelt en røye stjerne som ikke lenger heter s,
det i stedet heter, buffer-- så la oss trekke variabelen navn
nå som buffer-- om jeg har ikke kalt getString eller malloc her,
som effektivt gjør at buffer er bare noen søppel verdi.
>> Nå hva betyr det?
Det betyr at jeg har fortalt scanf å forvente en streng fra brukeren.
Og vet du hva?
Uansett hva denne tingen peker til-- og jeg tegner spørsmålstegn,
men i virkeligheten, det kommer til å være noe sånt OX1, 2, 3, ikke sant?
Det er noen falsk verdi som bare skjer for å være der fra før.
Så sagt på en annen måte, er det som om buffer er bare
peke på noe i minnet.
Jeg aner ikke hva.
>> Så hvis jeg skriver i Gabe nå, det kommer å prøve å sette g-a-b-e / 0 der.
Men hvem vet hva det er?
Og i det siste, noe gang vi har prøvd å røre
minne som ikke hører til oss, hva har skjedd?
Eller nesten hver gang.
Segmentering feil, ikke sant?
>> Denne pilen, jeg har ingen anelse om hvor det er peker. det er bare noen tilfeldig verdi.
Og selvfølgelig, hvis du tolker en tilfeldig verdi som en adresse,
du kommer til å gå til noen tilfeldig destinasjon.
Så Gabe kan faktisk krasj mitt program i dette tilfellet her.
>> Så hva kan vi gjøre som er nesten like ille?
Tenk på dette tredje og siste eksempel på scanf.
Denne versjonen er bedre i hvilken forstand?
Hvis du er komfortabel med Forrige problem, dette er bedre.
Hvorfor?
>> PUBLIKUM: [uhørlig].
DAVID J. MALAN: Good.
Så dette tilfelle av linje 16 er bedre, i den forstand
at vi er eksplisitt allokere minne.
Vi bruker ikke malloc, vi bruker den uke 2
tilnærming av bare å erklære en matrise.
Og vi har sagt før at en streng er bare en rekke tegn,
så dette er helt legitim.
Men det er selvsagt, som du merke, fast størrelse, 16.
>> Så dette programmet er helt trygt, hvis jeg skriver
i ett tegnstrenger, to karakter strenger, 15 tegnstrenger.
Men så snart jeg begynner å skrive 16, 17, 18, 1000 tegnstrenger,
hvor er denne strengen kommer til å ende opp?
Det kommer til å ende opp med delvis her.
Men så hvem vet hva annet er utenfor grensene
av denne spesielle array?
>> Det er som om jeg har erklærte 16 bokser her.
Så i stedet for å trekke ut alle 16, vil vi bare late som at jeg har trukket 16.
Men hvis jeg da prøve å lese en streng det er mye lenger, som 50 tegn,
Jeg kommer til å begynne å sette a, b, c, d, x, y, z.
Og dette er antakelig noen andre minnesegment
som, igjen, kan forårsake mitt program til å krasje,
fordi jeg ikke har bedt om noe mer enn bare 16 bytes.
>> Så hvem bryr seg?
Vel, her er CS50 biblioteket.
Og mesteparten av dette er bare som instruksjoner opp toppen.
Den CS50 bibliotek, hele denne tiden, har hatt denne linjen på linje 52.
Vi har sett typedef, eller vil du se typedef
i PSet 4, som bare danner en synonym der røye stjerne kan være mer
ganske enkelt referert til som strengen.
Så dette er en av de få trening hjul
vi har brukt i hemmelighet under panseret.
>> I mellomtiden, her er funksjon, getchar.
Nå tydeligvis er det ingen kropp til det.
Og faktisk, hvis jeg holder rulling, det gjør jeg faktisk ikke
se noen implementeringer av disse funksjonene.
Som en mental helse sjekk, hvorfor er det?
>> PUBLIKUM: [uhørlig].
DAVID J. MALAN: Yeah.
Så dette er topptekstfilen.
Og header-filer inneholder prototyper, pluss noen andre ting, virker det,
som typedefs.
Men i CS50.c, som vi har aldri gitt deg direkte,
men har vært i CS50 apparatet alle denne gangen, dypt inne i sine mapper,
merke til at det er en hel haug av funksjoner her inne.
>> Faktisk, la oss bla nedover.
La oss se bort fra de fleste av dem, for nå.
Men bla ned til getInt og se hvordan getInt fungerer.
Så her er getInt.
Og hvis du noen gang virkelig brydde seg hvordan får int fungerer, her er dokumentasjonen.
Og blant de tingene den sier er den forteller deg
hva verdiområder det kan returnere.
Det er hovedsaklig negative 2 milliarder til positiv 2 milliarder, gi eller ta.
>> Og det viser seg, alt dette tid, selv om vi har aldri
du hadde se etter det, hvis noe går galt,
det viser seg at alle Foreløpig har getInt
vært tilbake en spesiell konstant, ikke null,
men heller int_max, som er bare en programmerer konvensjon.
Det betyr at her er en spesiell verdi.
Sørg for å sjekke om dette, bare i tilfelle noe går galt.
Men vi har aldri brydd med at til dags dato,
fordi igjen, denne er ment å forenkle.
>> Men hvordan getInt bli gjennomført?
Vel, en, tar det ingen argumenter.
Vi vet det.
Den returnerer en int.
Vi vet det.
Så hvordan fungerer det under panseret?
>> Så det er tydeligvis en uendelig sløyfe, i det minste utseende av en.
Legg merke til at vi bruker getString.
Så det er interessant. getInt kaller vår egen funksjon, getString.
Og nå hvorfor dette kan være tilfelle?
Hvorfor blir jeg defensiv her på linje 165?
Hva kan skje i tråd 164, bare for å være klar?
Det er det samme svaret som før.
Kan bare være ut av minnet.
Noe går galt med getString, vi må være i stand til å håndtere det.
Og grunnen til at jeg ikke kommer tilbake null er det, teknisk sett, er null en peker.
getInt har til å returnere en int.
Så jeg har vilkårlig besluttet, i hovedsak,
at 2 milliarder, gi eller ta, kommer å være en spesiell verdi som jeg kan aldri
faktisk komme fra brukeren.
Det er bare én verdi jeg skal å kaste bort for å representere en feilkode.
>> Så nå, ting blir litt fancy.
Og det er ikke helt den samme funksjonen som før, men det er svært lik.
Så legger merke til, erklærer jeg her, i tråd 172, både en int n og en char c.
Og så bruker jeg denne funky linje, sscanf, som det viser seg
skanner ikke en streng fra tastaturet.
Det står en eksisterende streng som brukeren allerede har skrevet i.
Så jeg allerede kalt getString, som betyr at jeg har en streng i minnet.
sscanf er hva du kaller en analysefunksjon.
Den ser på strengen jeg har skrevet inn, tegn for tegn,
og gjør noe nyttig.
At strengen er lagret i linje.
Og jeg vet at bare ved å gå sikkerhetskopiere her og si, oh, OK,
Jeg kalte det ikke s denne gangen, men linjen.
>> Og nå er dette litt annerledes.
Men dette betyr effektivt, av grunner vi vil noe bølge våre hender i dag,
at vi sjekker til se om brukeren skrev inn
og int og kanskje en annen karakter.
Hvis brukeren har skrevet i en int, er det kommer til å bli lagret i n, fordi jeg er
passerer dette ved adresse, nytt triks vi har sett i dag.
Hvis brukeren har også skrevet i like 123x, at x
kommer til å ende opp med en brev i karakter c.
>> Nå viser det seg at sscanf vil fortelle meg, intelligent,
hvor mange variabler ble sscanf med hell kunne fylle.
Så ved denne logikk, hvis funksjon Jeg implementere er getInt,
men jeg sjekker, potensielt, for brukeren
å ha skrevet i en int etterfulgt av noe annet,
hva vil jeg sscanf sin returverdien virkelig å være?
Hvis hensikten er å komme bare en int fra brukeren?
>> Så hvis sscanf avkastning 2, hva betyr det?
Brukeren har skrevet i noe sånt som, bokstavelig talt,
123x, som er bare tull.
Det er en feil, og Jeg vil se etter det.
>> Så hvis brukeren skriver dette i, ved denne logikken, hva gjør sscanf tilbake,
ville du si?
Så det kommer til å gå tilbake 2, fordi 123 kommer til å gå inn her,
og x kommer til å ende opp i her.
Men jeg ikke vil at x å få fylt.
Jeg ønsker å sscanf å bare lykkes i å fylle den første av variablene.
Og så det er derfor jeg ønsker sscanf å returnere en.
>> Og hvis dette er litt over hodet for øyeblikket, det er helt greit.
Innse skjønt, at en av de verdier av getInt og getString
er at vi gjør en pokker for en Mange feilkontroll som dette så
som til dags dato, kan du ganske mye skriver noe på tastaturet,
og vi vil ta det.
Og vi sikkert, personale, vil definitivt ikke
være kilden til en feil i din program, fordi vi er defensivt
sjekke for alle de dumme ting som en bruker kan gjøre,
som å skrive en streng, når du virkelig ønsket int.
Så for now-- vi kommer tilbake til dette før long--
men hele denne tiden, getString og getInt har
vært under panseret bruker denne grunnleggende ideen av adresser til hukommelsen.
>> Så nå, la oss gjøre ting litt mer brukervennlig.
Som du kanskje husker, fra Binky siste tid-- hvis min mus vil cooperate-- så
vi hadde denne koden, som ærlig, er ganske meningsløse.
Denne koden oppnår ingenting nyttig, men det var eksempelet
at professor Parlante anvendes for å representere
hva som foregikk i en program som involverer hukommelse.
>> Så la oss gjenfortelle dette Historien super kort.
Disse første to linjer, i Engelsk, hva ville du si?
Bare i rimelig menneskelig, men litt tekniske termer, ta et stikk.
PUBLIKUM: [uhørlig].
>> DAVID J. MALAN: OK, du etablere adresser for din x og y-variabler.
Ikke helt, fordi x og y ikke er variabler i tradisjonell forstand.
x og y er adresser eller vil lagre adressen.
Så la oss prøve dette på nytt.
Ikke en dårlig start, skjønt.
Yeah?
>> PUBLIKUM: [uhørlig].
DAVID J. MALAN: Good.
Jeg tror det er litt renere.
Erklærte to pekere, to heltall.
Og vi ringer dem x og y.
Eller hvis vi skulle trekke dette som et bilde, igjen,
husker rett og slett at alle vi gjør med den første linjen
er å tegne en boks som dette, med en viss verdi i den søppel,
og kaller det X, og en annen boks som dette,
med noen søppel verdi i det, kaller det y.
Vi har erklært to pekere som til slutt
vil lagre adressen til en int.
Så det er alt der.
>> Så når Binky gjorde dette, leire bare så ut som dette.
Og Nick bare slags pakket opp pilene,
som om de ikke peker noe sted spesielt, fordi de er bare
søppel verdier.
De er ikke eksplisitt initialisert hvor som helst i særdeleshet.
>> Nå er det neste linje kode, husker, var dette.
Så i rimelig brukervennlig, men noe teknisk engelsk,
hva er denne linjen med kode gjør?
Yeah?
>> PUBLIKUM: [uhørlig].
>> DAVID J. MALAN: Perfect.
Det er å fordele den del av minne som er på størrelse med en int.
Og det er halve svaret.
Du svarte riktig halvparten av uttrykket.
Hva som skjer på venstre side av likhetstegnet?
Yeah?
PUBLIKUM: Og redere det til variabelen x?
>> DAVID J. MALAN: Og redere det til variabelen x.
Så til oppsummering, høyre side Tildeler nok minne til å lagre en int.
Men malloc spesifikt returnerer adressen
av at mengde minne, som du har bare foreslått blir lagret i x.
>> Så hva Nick gjorde sist gang med Binky er han dro at pekeren ut, leire,
å peke nå på en hvit blings av minne som er lik størrelsen på en int.
Og ja, som er ment å representere fire byte.
>> Nå, den neste linje med kode gjorde dette, stjerne x blir 42.
Så 42 er grei på høyre side, meningen med livet.
Venstre side, betyr stjerne x hva?
Som også kan ha gone-- det er OK.
OK.
>> PUBLIKUM: I utgangspunktet, gå til [uhørbart]
DAVID J. MALAN: Good.
PUBLIKUM: [uhørlig].
DAVID J. MALAN: Nettopp.
Venstre del gå til x.
x er adressen.
Det er som 33 Oxford Street, eller OX1.
Og stjerne x betyr gå til den ta og sette det der ute?
42.
>> Så ja, det er akkurat hva Nick gjorde.
Han startet med ved, i hovedsak, mentalt
peker en finger på x, etter pilen
til den hvite boksen på høyre hånd side, og å sette nummer 42 der.
Men så fikk en litt farlig, ikke sant?
Binky er i ferd med å miste hodet.
>> Stjerners y er lik 13, uflaks, betyr hva?
Så stjerne y del gå til adressen i y.
Men hva er adressen i y?
Greit, det er søppel verdi, ikke sant?
Jeg tegnet det som et spørsmålstegn.
Nick trakk det som en krøllet opp pil.
Og så snart du prøver å Star y, sier dra dit,
men det er ikke en legitim adresse, er det noen falsk beliggenhet,
programmet kommer til å krasje.
Og Binky hode kommer å fly av her, som det gjorde.
>> Så til slutt, dette programmet var bare flate ut feil.
Det var en buggy program.
Og det behøvde å bli bestemt.
Og den eneste måten, egentlig, for å fikse det vil være, for eksempel, denne linje,
som vi ikke engang få til, fordi programmet krasjet for tidlig.
Men hvis vi skulle fikse dette, hva Effekten gjør gjør y lik x ha?
Vel, i hovedsak peker den y på uansett verdi x peker på.
>> Så i Nick historie, eller Binky historie, både
x og y var peker på den hvite del av minnet,
slik at, til slutt, når du Star y lik 13 igjen,
du ender opp med å sette 13 i riktig sted.
Så alle disse linjer er helt legitim, bortsett fra denne ene,
når det skjedde før du faktisk tildelt y noen verdi.
>> Nå heldigvis, trenger du ikke nødt til å resonnere gjennom alle
av slike saker på egen hånd.
La meg gå videre og åpne opp et terminalvindu her
og åpne opp, for bare et øyeblikk, en super kort program som
også er slags meningsløs.
Den er stygg.
Det oppnår ikke noe nyttig.
Men det gjør demonstrere problemer minne, så la oss ta en titt.
>> Main, super enkelt.
Det krever tydeligvis en funksjon, f, og deretter returnerer 0.
Det er litt vanskelig å rote dette opp.
Så Main er ganske bra, så langt.
>> Så f er problematisk.
Og bare ikke legge mye arbeid i å navngi den
her, for å holde fokus på koden.
f har to linjer.
Og la oss se hva som nå skjer.
Så på den ene side her-- og la meg gjøre
dette sammenfallende med tidligere example-- på den ene side,
venstre side er gjør hva, på engelsk?
Det er--
PUBLIKUM: Lage en peker.
DAVID J. MALAN: Lage en peker til en int og kaller det x.
Så det å lage en av disse boksene Jeg holder tegning på berøringsskjermen.
Og nå, på høyre hånd side, malloc naturligvis
er å fordele en del av minnet.
Og bare for å være klar, hvordan mye minne er det tilsynelatende
tildeling, hvis du bare slags gjøre regnestykket her?
>> Så det er 40 bytes.
Og jeg vet at bare fordi jeg vet en int, på CS50 apparatet, i det minste
er fire byte.
Så 10 ganger 4 er 40.
Så dette er lagring av en x, adressen av det første av 40 ints at
har fått tildelt plass tilbake, til rygg, og bakover, mot rygg.
>> Og det er det som er nøkkelen om malloc.
Det tar ikke et lite minne her, litt her, litt her.
Det gir deg en del av minnet, tilgrensende, fra operasjons
system.
>> Hva nå om dette, x brakett 10 lik 0?
Vilkårlig linje med kode.
Det oppnår ikke noe nyttig.
Men det er interessant, fordi x brakett 10--?
Yeah?
>> PUBLIKUM: [uhørlig]?
>> DAVID J. MALAN: x brakett 10 trenger ikke å være null.
Null detalj kommer bare inn i bildet med strenger, ved enden av en streng.
Men en god tanke.
>> Hvor stor er denne matrisen, selv om jeg har frigjort 40 bytes?
Det er 0 til ni, ikke sant?
Det er 10 ints, totalt.
40 bytes, men 10 ints, indeksert 0 til 0.
>> Så hva er det x brakett 10?
Det er faktisk noen ukjent søppel verdi.
Det er minne som ikke tilhører meg.
Jeg skal ikke berøre det byte nummer 41, 42, 43, 44.
Jeg kommer litt for langt.
>> Og ja, hvis jeg kjører dette program, kan det meget vel krasje.
Men noen ganger, vil vi få heldige.
Og så bare for å demonstrere dette-- og ærlig,
du vet aldri før du gjør it la oss kjøre dette.
Det gjorde faktisk ikke krasje.
>> Men hvis jeg endre dette, for eksempel, til å være som 1,000,
å gjøre dette virkelig bevisst, la oss se
hvis vi kan få den til å krasje denne gangen.
OK, det gjorde ikke krasje.
Hva med 100.000?
La oss remake det, og nå kjøre den.
OK.
Phew.
Greit.
Så tilsynelatende, igjen, disse segmenter av minne, så å si,
er rimelig stor, så vi kan få heldige igjen og igjen.
Men til slutt, når du får latterlig og virkelig gå langt ut på skjermen,
du berører minne som virkelig, egentlig ikke tilhører deg.
>> Men ærlig talt, disse typer feil kommer
å være hardere og hardere å finne ut på egen hånd.
Men heldigvis, som programmerere, har vi verktøy som tillater oss å gjøre dette for oss.
Så dette er kanskje en av de styggeste programmer,
enda styggere enn gdb utgang.
Men det har alltid en linje eller to som er super nyttig.
>> Valgrind er et program som hjelper du ikke feilsøke et program, per se,
men finner minne-relatert problemer, spesielt.
Det vil automatisk kjøre koden din for deg og se etter minst to ting.
One, har du gjort noe utilsiktet lignende touch minne
som ikke tilhører deg?
Det vil hjelpe deg å finne disse tilfellene.
>> Og to, vil det hjelpe du finner noe som heter
minnelekkasjer, som vi har fullstendig ignorert, naivt,
for en tid og et trettitalls.
Men det viser seg, alt dette tidspunkt, når
du har kalt getString i så mange av våre programmer,
du spør drifts system for minne,
men du har noen erindring av stadig å gi det
tilbake, gjør unalloc, eller fri, som det heter.
Nei, fordi vi har aldri ba deg om å gjøre det.
>> Men alt denne gangen, programmene du har skrevet i C
har vært lekker minne, spør drifts
system for mer og mer minne for strykere og whatnot,
men aldri levere det tilbake.
Og nå er dette litt av en overforenkling,
men hvis du noen gang har kjørt din Mac eller PC for en stund, åpning
mange programmer, kanskje lukke programmer,
og selv om din Datamaskinen har ikke krasjet,
det blir så mye tregere, som om det er virkelig
bruker mye minne eller ressurser, selv om,
hvis du ikke selv å trykke på tastaturet,
som kunne be-- men ikke always-- kunne være at programmene du kjører
har selv minnelekkasjer.
Og de fortsette å spørre OS for mer og mer minne, men glemme det,
faktisk ikke bruke det, men derfor tar minne bort
fra andre programmer som kanskje ønsker det.
Så det er en vanlig forklaring.
Nå her er der Valgrind sin produksjonen er helt
fryktelig til de mindre og mer like komfortabel.
Men det interessante ting er rett her oppe.
Det er å fortelle meg en ugyldig skrive av størrelse fire som skjer i dette programmet,
Særlig i linje 21 av memory.c.
>> Hvis jeg går til linje 21, hm, det faktisk er en ugyldig skrive av størrelse fire.
Hvorfor størrelse fire?
Vel, dette number-- og det kan være noe-- er en int.
Så det er fire byte.
Så jeg setter fire bytes der de ikke hører hjemme.
Det er det Valgrind er faktisk å fortelle meg.
Videre vil det også fortell meg, så vi får se,
som du kjører dette i en fremtidig PSet, hvis og når du har lekket minne, som faktisk
Jeg har, fordi jeg har kalt malloc, men jeg har faktisk ikke
heter, i dette tilfellet, fri, som vi vil til slutt se
er det motsatte av malloc.
>> Så nå, tror jeg, en siste eksempel.
Så dette er litt mer uforståelige, men det er kanskje
den største grunnen til være forsiktig med minne,
og på grunn av at mange programmer og / eller webservere, selv til denne dagen,
overtas av skurkene sted på internett som er en eller annen måte
sende falske pakker til serveren din prøver å kompromittere kontoene dine,
eller ta dine data, eller bare som regel overtar en maskin.
Buffer overløp, som navnet antyder, betyr
fylte ikke en int, men en buffer.
Og en buffer er bare en fancy måte for å si det er en haug med minne.
>> Og ja, jeg ringte en streng før buffer, i stedet for s.
For hvis det er en buffer, som i YouTube forstand,
eller helst du ser på en video, du kanskje har sett ordet bufring,
prikk, prikk, prikk.
Det er utrolig irriterende.
Og det betyr bare at din videospiller
prøver å laste ned masse byte, masse bytes
fra en video fra internett.
Men det er treg, så det er prøver å laste ned en haug av dem
å fylle en buffer, en beholder, slik at du har nok byte som det kan da
vise deg videoen, uten pause hele tiden.
Men det viser seg, kan du ha en buffer til denne store.
Men prøv å sette dette mye data i det, og veldig dårlige ting kan skje.
Så for eksempel, la oss se på dette siste teaser av et eksempel.
Dette er et annet program som, ved første øyekast,
gjør ikke noe super nyttig.
Det har en hovedfunksjon som kaller denne funksjonen, f.
Og den funksjonen, f, her oppe, har en char array, kalt c, på størrelse 12.
Og så er det ved hjelp av dette ny funksjon kalt strncpy.
>> Det viser seg at med denne enkle, enkel linje med kode, bare to linjer,
vi har gjort hele mitt program, og derfor hele min datamaskin,
og min brukerkonto, og mine hardt kjøre potensielt sårbar for alle
som kjenner og er god nok til å kjøre dette programmet med en viss kommandolinje
argument.
Med andre ord, hvis denne skurken setter innsiden av argvargv [1] ved å skrive
på tastaturet en meget spesiallaget streng, ikke abc, 123, men i hovedsak,
binære symboler som representerer kjørbar kode, et program som han eller hun skrev,
Med denne enkle program, som er representant for tusenvis av programmer
som er like sårbare, daresay, han eller hun kan til slutt slette alle
filene på harddisken min, få en blinkende teksten slik at han eller hun kan
skriver kommandoer på egen hånd, e alle filene til meg selv.
Noe jeg kan gjøre, han eller hun kan gjøre med denne koden.
>> Vi vil ikke helt løse dette ennå.
Og faktisk, det kommer til å innebære et lite bilde
som dette, som vi vil snart komme å forstå alle bedre.
Men for i dag, la oss avslutte på hva er, forhåpentligvis, en litt mer
forståelig XKCD spøk, før vi fortsette neste gang.
Greit.
Ser deg på onsdag.
>> [Musikk spilles]
>> SPEAKER: Og nå, dyp tanker, etter Daven Farnham.
Minne er som å hoppe inn i en haug av gylne blader på en søndag ettermiddag.
Vinden blåser, kaste din hair-- oh, jeg savner dagene when--
>> [Latter]