>> [Musikk spilles]
>> DAVID J. MALAN: Ok dette er CS50 og dette er begynnelsen av uke fem.
Så i dag, under dine sitteputer, du vil ikke finne noe.
Men ovenfor, bør du finne disse, en lite tegn på vår takknemlighet for
alt arbeidet som du putter inn i Game of Fifteen.
Bare fjerne den lille sirkelen på bunnen for å begynne å spille for
resten av klassen.
>> Så husker det, eller vet at problemet satt fire, som gikk ut denne helgen,
innebærer å skrive et annet spill.
Men denne gangen er det innebærer å bruke en Selve grafisk brukergrensesnitt, ikke en
tekstgrensesnittet som Game of Fifteen var.
Og spillet som ligger foran deg, Hvis du ennå ikke har sett denne siden,
ser litt noe sånt som dette.
Jeg kommer til å gå inn i terminalen min vinduet her i GDB.
Og jeg kommer til å gå foran og kjør Personalet løsning, som du kan få tilgang til
etter å ha kjørt update 50 som vanlig.
>> Men jeg kommer til å sette den inn i en liten hemmelig modus, litt påskeegg,
såkalte Gud modus, ved sette Gud i argv1.
Og jeg må følge mine egne retninger, kjører det i min egen
Problemet satt katalogen.
Så nå kan du se en fullstendig versjon av spillet Breakout.
Faktisk er dette no-hands-modus.
Så det er faktisk -
imponert om du kan være -
ganske trivielt å implementere Gud modus i Breakout, i motsetning til Game of Fifteen,
som noen av dere kanskje har taklet for hacker-utgaven.
>> I Breakout er det nok på Gud modus for å rett og slett gjøre hva,
intuitivt med padle?
Bare gjøre den lik uansett horisontal posisjon er denne omgangen.
Og så lenge du gjør dette i lockstep med ballen beveger dette spillet vil
aldri, aldri, aldri glipp ballen og du vil vinne hver gang.
>> Men i denne ukens hacker utgave det er mer enn bare Gud modus.
Det er en rekke andre funksjoner.
Blant dem, lasere.
Slik at hvis du virkelig bli utålmodig deg kan begynne å skyte ned mursteinene
og noen få andre.
Og for de av dere som ønsker å kalibrere standard versus hacker
utgave, kan jeg se at denne ukens hacker utgaven er bevisst en
litt mer gjennomførbart, sier, enn Gud modus var med Game of Fifteen.
>> Så hvis du leter etter en strekk og du leter etter noen ekstra moro
funksjonene gjør dykk i hvis interesse.
Nå mer praktisk, la meg peke ut en ting i tillegg.
GDB, som noen av dere kanskje ikke har ennå rørte personlig, noe som er fint.
Men er nå virkelig på tide å venne til dette og komfortabel med dette verktøyet
fordi det vil gjøre livet mye enklere, virkelig.
>> Per Rob foredrag på GDB et par uker siden, husker
at GDB er en debugger.
Det er et verktøy som lar deg kjøre din programmet, men kjøre det steg for steg, linje
for linje, slik at du kan rote rundt, slik at du ser ting skjer, så
som du kan skrive ut verdiene av variablene.
Kort sagt, det gir deg så mye mer strøm enn printDef gjør.
>> Nå riktignok, grensesnittet er ganske uforståelige.
Svart og hvitt tekstgrensesnittet for det meste.
Kommandoene er litt tøff å huske på først.
Men selv om det kan ta deg en halv en time, en time, for å sette det på forhånd
investering av tid til det, stole på meg.
Gjerne ved semesterets slutt vil det spare du en størrelsesorden mer
tid enn.
>> Så tidlig i uken dykke i.
Og når det gjelder Breakout, vet at du kan gjøre dette så lenge du har
fordelingen kode eller din egen kode pågår i din Pst4 katalogen.
Vit at du kan kjøre gdb. / Avslapnings.
>> Dette kommer til å åpne opp et vindu som dette.
La meg gi meg selv mer av en terminal vindu.
Og så hva jeg kommer til å gå videre og gjøre, det er ikke bare kjøre den.
Jeg kommer til å først sette et knekkpunkt tilbakekalling, som lar deg pause
utførelse på et bestemt sted.
>> Bare for å holde ting enkelt jeg kommer å bryte på linjen man bare ved å skrive
nummer én.
La meg faktisk re-åpne dette vinduet fordi det blir en
litt liten der.
Så hva jeg nå skal gjøre her er hvis jeg åpner opp min terminal-vinduet.
Kom igjen, det vi går.
>> Så nå hvis jeg går tilbake til dropbox, Pst4 og kjøre gdb. / breakout inn, merker
Jeg kommer til å bryte en å sette en pause poeng på én.
Og nå skal jeg til å gå fremover og type kjøre.
Og når jeg gjør det, merker ingenting synes å skje.
>> Det er ingen pop up.
Det er ikke noe grafisk brukergrensesnitt ennå.
Men det er forståelig fordi jeg er bokstavelig talt på linjen en i mitt program.
Og legg merke til at jeg har fast videresendt, spesielt nå til 62, fordi alle
ting på toppen av denne filen er ting som kommentarer og konstanter og
uinteressant ting for nå.
>> Så nå er jeg inne i main, det virker, på linje 62 år.
Og dette er bare fordelingen kode, tilbakekalling.
Hvis jeg åpner dette opp ved å gå, på samme måte, inn i min slippe boksen til katalogen Pst4,
inn breakout.c.
Og hvis jeg ruller ned og ned og ned, og la meg gå videre og slå på
mine linjenummer.
>> Hva jeg vil se, hvis jeg blar ned til linje 62, er nøyaktig den linje som
vi har stoppet på.
Så denne linjen her, 62, er hvor vi er i ferd med å bli.
Så nå i GDB, hvis jeg går videre og skriver nå neste, skriv det kommer til å
kjøre den linjen.
Og voila, har vi såkalte g-vinduet.
Hvis kjent med hva en GWindow er, for ikke å bekymre deg.
Den spec vil introdusere deg til den, som samt en rekke walkthrough videoer
innebygd i spec.
>> Men nå la oss gjøre dette til en litt mer interessant.
La meg flytte dette vinduet over til siden litt.
La meg gjøre vinduet litt større, slik at jeg kan se mer.
>> Og nå la meg gå videre og gjøre neste gang.
Og det er mine murstein.
Hvis jeg skriver neste gang nå ser jeg på ballen.
Og hvis jeg skriver neste gang nå ser jeg padle.
>> Og heldigvis dette gedit er ikke virkelig samarbeide ved å vise meg
alt jeg vil.
Men nå hvis jeg gjør neste gang, neste gang, jeg er bare
erklære noen variabler.
Og jeg kan skrive ut en av disse gutta ut.
Skriv ut murstein, utskrifter liv.
>> Og nå hvis jeg fortsetter å gjøre neste, merker at jeg vil være
innsiden av det loop.
Men koden kommer til å utføre akkurat som jeg forventer.
Så når jeg treffer denne funksjonen, Vent for klikk, det kommer til å gjøre
det bokstavelig talt det.
Så jeg syntes å ha mistet kontrollen over programmet.
>> GDB er ikke å gi meg et annet spørsmål.
Men ikke å bekymre deg.
Gå til spillet mitt, klikker du et sted.
>> Og voila, nå fortsetter til linje 86.
Så igjen, det er uvurderlig, til slutt, for debugging problemer.
Fordi du kan bokstavelig talt gå gjennom koden, print ut ting og mye,
mye, mye mer.
Men for nå, disse verktøyene alene bør få deg ganske langt.
>> Så vi er, selvfølgelig, å ta en titt på Graphics nå, plutselig.
Og nå vår verden blir litt mer interessant.
Og du vet, kanskje, fra noen av de videoer på nettet at vi har disse
shorts som du har vært å se som en del av oppgavesett.
>> Og de har blitt skutt, bevisst, mot en hvit bakgrunn.
, Og noen av dem har læren Fellows tegning litt tekst på
skjerm som er kledde på siden av dem.
Men selvfølgelig, dette er ikke alt som interessant i den virkelige verden.
Dette er bare en forelesningssal med en stor hvit skjerm og et bakteppe.
Og vår fantastiske produksjonsteamet slags av gjør alt ser vakker
i ettertid ved beskjæring ut eller overliggende noe
vi gjør eller ikke vil ha.
>> Nå bare for å motivere denne uken og egentlig, hvor du kan gå, til slutt,
med informatikk.
Ikke like etter problem satt fire.
Men etter et annet kurs eller en hel læreplanen er det utrolig hva du kan
gjøre for tiden når det gjelder grafikk spesielt.
>> Noen av dere har kanskje sett dette flyter rundt på nettet.
Men jeg tenkte jeg skulle vise dere, for bare en par minutter, et glimt av hva
datateknologi og hva CGI, datagrafikk kan gjøre i disse dager
med en kjent sang og kanskje film.
>> [MUSIC - LANA DEL RAY, "Ung og vakker]
>> SPEAKER 1: Det er bare en liten bit fantastisk, kanskje, hvor
allestedsnærværende -
>> [APPLAUSE]
>> SPEAKER 1: Jeg har nettopp lastet det ned.
Men det er virkelig fantastisk, tror jeg, bare hvor allestedsnærværende programvare og kode og
verktøy som dette egentlig er.
Så det er en smak av retning hvor du kan gå.
Å, ikke mer Appliance i dag.
Vel, det er faktisk tragisk timing gitt det punktet jeg bare prøvde å gjøre.
>> Ok, så la oss starte Fusion igjen.
Minn meg senere.
Greit, og du bør ha fått en e-post som en side hvis du fikk en
legge merke til sånt.
All right, så husker at forrige uke vi begynte å skrelle tilbake
senere kjent som streng.
>> string minnes en datatype som er deklarert i CS50 biblioteket.
Og det er en del av trening hjul som nå begynner å ta av.
Det var et nyttig begrep tidlig.
Men nå kommer det til å få mer interessant og kraftigere til
faktisk se at under panseret, en streng er akkurat det, vi sa?
>> Ja, så det er en såkalt røye *.
Og * det indikerer at det ikke er en slags adresse involvert.
Og så når du sier røye * du bare bety en variabel med datatype er en
pekeren nå.
Det faktum at det er stjernen det betyr bare at du er erklære en
såkalt pekeren.
Og at pekeren skal tilsynelatende lagre adressen, av
Selvfølgelig, en røye.
>> Nå hvorfor dette fornuftig?
Vel, hva er en streng under panseret?
Vel, i noen tid har vi vært å si at en streng under panseret er
bare h-e-l-l-O, for eksempel.
>> Men vi har snakket om dette som være, i hovedsak, en matrise.
Og en rekke ville da se litt mer som dette, med hver av disse
tar opp en bit.
Og så har vi sagt at det er noe spesielt tilbake hit, det
0 backslash, eller null terminator.
>> Så hele denne tiden, dette her har vært en streng.
Men egentlig, er en streng faktisk en adresse.
Og adresser, som vi skal se, er ofte prefiks med 0x av konvensjonen.
Hva betegne 0x?
Vet noen?
>> Så det betyr bare heksadesimal.
Så du kanskje husker, faktisk, fra PST 1, tror jeg, en av de varme opp
spørsmål spurte faktisk om heksadesimal notasjon i tillegg til
binær og desimal.
Og motivasjonen her er at med heksadesimal har du 16
sifre til din disposisjon.
0, etterfulgt 1, 2, 3, 4, 5, 6, 7, 8, 9, ved a, b, c, d, e, f.
>> Og hvis du teller alle dem opp, du får til sammen 16 år.
Så dette er i kontrast med desimal, hvor vi har 10
sifre, 0 til ni.
Det er i kontrast med binære hvor vi må bare 0 og 1.
>> Men på slutten av dagen kan du bare representerer de samme tallene, men
noe annerledes.
Og heksadesimal er vanlig fordi som det viser seg - og vi vil se dette
senere i kurset - selv når vi får til web-programmering i sammenheng med
HTML og fargekoder, heksadesimal er fint.
Fordi hvert siffer, viser seg, representerer fire biter perfekt.
Så det bare slags linjer opp pent som vi vil til slutt se.
Så dette kan være Ox123 eller noe sånn, betegner adresse 123
et sted inne i min datamaskinens minne.
>> Men selvfølgelig, noen problemer oppstår på grunn av dette underliggende
gjennomføring.
Og husker at jeg tok en stikke på implementere en funksjon som dette -
sammenligne dash 0 dot c forrige uke, at selv om det så ut som det var
rett, det rett og slett ikke sammenligne to strenger korrekt.
>> Jeg har kastet bort viktigste, og jeg har kastet bort kommentarene bare for å fokusere på
koden som er av interesse her.
Og det er i rødt fordi det er buggy.
For hvilken grunn?
>> Vel, på toppen der da jeg erklærte en streng, var det som virkelig skjer
under panseret?
Vel, la meg gå over til skjermen her og tegne det.
Så jeg erklærte, igjen, string s GetString.
>> Så jeg kommer til å gå videre nå og tegne s for hva det egentlig er.
Det kommer til å være et kvadrat her.
Og jeg kommer til å kreve at det er 32 bits.
I det minste er det vanligvis, minst på CS50 den
apparatet i en rekke datamaskiner.
Jeg kommer til å kalle det s.
>> Men nå husker at vi kalt GetString.
Så GetString avkastning, selvfølgelig en streng.
Hvis brukeren skriver i h-e-l-l-o inn strengen hallo blir returnert.
Og at strengen, som vi sa, ender opp et sted i datamaskinens minne
med en omvendt skråstrek 0 på slutten.
Jeg vil trekke dette som array - eller sammenhengende blokk tegn -
at det faktisk er.
>> Og nå, er hva GetString faktisk tilbake?
Hva har GetString vært tilbake hele denne tiden?
Vel, vi sier, i uker før, den returnerer en streng.
Men mer teknisk, hva gjør GetString retur tilsynelatende?
>> PUBLIKUM: En adresse.
>> SPEAKER 1: En adresse.
Spesielt er det returnerer adressen av den aller første bitt, uansett hva det er.
Jeg bare fortsette å bruke en, to, tre fordi det er praktisk.
>> Den returnerer adressen til den første tegnet i strengen.
Og vi sa forrige uke at som er tilstrekkelig.
Fordi vi kan alltid finne ut hvor enden av strengen bare ved
iterating over det, kanskje, med en for loop eller en while-loop eller noe sånt
det, bare på jakt etter "backslash 0", den spesielle sentinel karakter.
>> Og da vet vi at strengen skjer for å være av lengde -
i dette tilfellet -
fem.
Så teknisk sett hva GetString gjør er den returnerer Ox123 i dette tilfellet.
Og teknisk hva som da skjer er at vi lagrer, innsiden av s, Ox123.
På slutten av dagen, selv om denne er nytt konsept, pekere, de er
bare variabler.
Men de måtte lagre biter som kollektivt representerer en adresse.
Så teknisk sett alt de får lagret i s er Ox123.
>> Men vi som mennesker -
inkludert dag og framover -
er egentlig ikke kommer til å bry seg, typisk, hva den faktiske adressen er
av noen del av minnet.
Det er bare å lavt detaljnivå til være intellektuelt interessant.
Så jeg kommer til å angre dette.
Og i stedet, mer høyt nivå, bare si at når vi snakker om pekere
Jeg skal bare trekke mer brukervennlig pil som formidler
samme idé og abstracts unna de opplysninger om hva den faktiske
underliggende adresse er.
>> Nå hvis vi går tilbake til koden, hva skjedde sist uke om vi har streng t
tilsvarer GetString?
Vel, hvis jeg igjen, skriver hallo denne gangen skal jeg få
en annen del av minnet.
h-e-l-l-o 0 skråstrek.
>> Men fordi jeg ringte GetString en andre gang -
og jeg vet dette fra å se på kildekoden for GetString - selv
om det er tilfeldig at hallo var skrevet inn to ganger, er GetString ikke
kommer til å forsøke å optimalisere og være flink.
Det er bare kommer til å få en annen del av minne fra datamaskinen, noe som er
kommer til å være på en annen adresse.
La oss vilkårlig bare si 456.
>> Og hva går det å komme tilbake?
Det kommer til å gå tilbake 456 og lagre den i t.
Så hva som egentlig skjer, på venstre side er at jeg har en annen del
minne, 32 bits typisk.
Og det kommer til å gå Ox456.
Men igjen, jeg er ikke interessert i disse spesielle numre lenger.
Jeg skal bare abstrakt tegne det som en pil.
>> Så dette er nå en ny forklaring.
Men det er de samme idé som er skjedd hele denne tiden.
Og så den grunn, så, at denne først versjon av sammenligne var buggy
forrige uke er hvorfor?
Når du gjør hvis s er lik lik t hva er du virkelig
under panseret sammenligne?
>> Du sammenligner adressene.
Og akkurat intuitivt, tydelig, Ox123 ikke kommer til å like Ox456.
Disse tallene, de biter er bare annerledes.
>> Og så konsekvent, i forrige uke det sagt du skriver forskjellige ting, selv om
Ordene var ordrett det samme.
Så vi fikse dette.
I lekmann vilkår, hva var fix?
>> PUBLIKUM: Bruk en funksjon.
>> SPEAKER 1: Bruk en funksjon.
Eller stjerner er definitivt involvert, men bruker en funksjon for å gjøre hva?
>> PUBLIKUM: Å sammenligne strengene.
>> SPEAKER 1: Å sammenligne strengene.
Så det grunnleggende problemet her var at jeg bare vurderer
Kvaliteten av strenger som skal defineres av sammenligning av deres adresser.
Og selvsagt det er bare dumt nå en gang du forstår hva som skjer
under hetten.
For virkelig å sammenligne strenger å se om de er like på den måten at et menneske
ville vurdere to strenger å være lik vi trenger å sammenligne dem karakter for
tegn for tegn.
>> Nå kunne jeg ha gjort dette veldig ordinært.
Men familiarly, vi ved hjelp av en for-løkke.
Og bare sammenligne s brakett jeg mot t brakett jeg.
s brakett i pluss en mot t brakett I pluss en, og så videre, inne
en slags løkke.
Og hvis jeg øye på to tegn som forskjellig, eller om jeg innser at ooh, er s
kortere enn t eller lengre enn t Jeg kan umiddelbart si falskt,
de er ikke det samme.
>> Men hvis jeg får gjennom s og t og si samme, samme, samme, samme, samme, slutten av
begge strenger, kan jeg si sann, er de like.
Vel, heldigvis, år siden noen skrev at koden for oss.
>> Og de kalte det StrComp for streng sammenligne.
Og selv om det er en liten counter intuitive, returnerer StrComp 0 hvis de
to strenger, s og t er like.
Men den returnerer negativ verdi hvis s bør komme før t alfabetisk eller
positiv verdi dersom det skulle komme etter t alfabetisk.
>> Så hvis du noen gang ønsker å sortere noe, det viser seg at StrComp er nyttig.
Fordi den ikke bare si ja eller nei, lik eller ikke.
Det gir deg en følelse av bestilling liker en ordbok makt.
Så StrComp, lik s komma t lik 0 betyr at den
strenger er virkelig like.
Fordi den som skrev denne funksjonen år siden antagelig brukt en for loop
eller en while-loop eller noe sånt å integrere over karakterene igjen
og igjen og igjen.
>> Men problemet to oppsto her.
Dette var copy0.c.
Og de to i rødt er fordi det er feil.
Og hva gjorde vi gjøre her?
Vel, første jeg ringte GetString.
Og jeg lagret avkastningen verdien i s.
Så det er ganske mye det samme som denne øverste delen av bildet.
>> Men hva kommer etter det?
Vel, la meg gå videre og bli kvitt av en hel haug med dette.
Vi vil spole tilbake i tid til der vi bare har s, som nå er i samsvar med
linjen der oppe.
>> Jeg sjekke.
Hvis s er lik lik 0.
Nå, en rask side note, når kan GetString returnere 0?
Det er ikke nok minne.
Høyre?
>> Det er sjelden at dette kommer til å skje, sikkert på en datamaskin som er
fikk hundrevis av megs eller selv gigabyte RAM.
Men det kan, i teorien, returnere 0, særlig hvis den
bruker ikke samarbeider.
Det er måter å late som om du ikke har Angitt noe og triks
GetString i retur 0 effektivt.
>> Så det kommer til å se etter det.
Fordi hvis noen av dere har begynt å få, allerede, segmentering feil -
som trolig har vært en kilde av litt frustrasjon -
de er nesten alltid resultatet av feil i minne.
Somehow du søl opp med hensyn til en pekeren, selv om du ikke visste
Det var en peker.
Så du kan ha indusert segmentering feil så tidlig som uke en bruker
noe som en for løkke eller en stund sløyfe og en rekke ved å gå for langt
forbi grensene av noen matrise som du erklært, i uke to i
særlig.
>> Du har kanskje gjort det selv i problemet satt fire med Breakout.
Selv om du sannsynligvis ikke har sett noen stjerner i fordelingen koden for
Breakout, viser det seg at de GRect og Goval og andre slike ting,
de er faktisk pekere under hetten.
>> Men Stanford, som oss, liksom skjuler at detaljer i hvert fall for bibliotekene
formål, mye som vi gjør for streng og røye *.
Men GRect og Goval og alle de ting dere er eller skal bruke
denne uken er slutt minneadresser.
Du vet bare ikke det.
>> Så det er ikke overraskende da, kanskje, som du kanskje turen over noen
segmentering feil.
Men det som er interessant her nå, hvis etter vi se etter 0 vi gjør
string t får s.
Vel, la meg erklære t.
Jeg kommer til å trekke det som en firkant, 32 biter, kall det t.
Og så skal jeg gjøre får s.
>> Vel, hva betyr det?
Vel, det er litt vanskelig å tenke om det bildet klok.
Men la oss tenke på hva som er inni av x?
Hva er bokstavelig talt inne i denne variabelen?
Verdien Ox123.
>> Så når jeg sier streng t får s, som bare bokstavelig talt betyr ta nummeret
i s, som er Ox123 og sette den Ox123.
Eller billedlig, hvis jeg slags abstrakt bort fra at detaljer den har
Effekten av bokstavelig talt å gjøre dette også.
>> Så nå tenker tilbake til forrige uke da vi gikk videre til kapitalistiske T. Jeg
gjorde T brakett 0.
Vel, T brakett 0, selv om det er en pekeren, kan du behandle det som om
det er en matrise, med en firkantet brakett notasjon.
>> Så hvor er T brakett 0?
Vel, det er h.
Og så når vi bruker den linjen med kode, to øvre, som er i det c type.h
header-fil, det er der den er deklarert.
Du utnytte denne H. Men av Selvfølgelig, det er nøyaktig samme h som er
innsiden av s, så å si.
Og så nå har du endret eller kapitalisert både den opprinnelige og den
så-kalte kopi.
Fordi du ikke lage en kopi i måte som et menneske ønsker den skal være.
>> Så hva var fix her, i copy1.c forrige uke?
Funksjoner, slik at vi kunne faktisk kopier strengen.
Og fundamentalt, hva vi trenger for å gjøre for å kopiere strengen?
>> Vel, i denne grønne versjonen her er jeg kommer til å gjøre det ganske lavt nivå.
Det er faktisk funksjoner de kunne hjelpe med dette.
Men det mest grunnleggende, og den mest kjent en, i det minste, vil snart være
kjent for oss, er følgende -
slik at en på den første linje av koden i grønt nå.
>> Jeg bare skrev s som røye *.
Det er ingen funksjonell forskjell der.
Jeg bare kastet bort CS50 bibliotek og Jeg kaller det hva det er, en røye *.
>> Nå prikk, prikk, prikk, fordi det var noen feilkontroll det er ikke
interessant å snakke om igjen.
Så nå t er deklarert.
Det er også en røye *.
Så jeg trakk opp en liten kvadrat skjermen som før.
>> Men på høyre side, malloc, vi sa er minne fordele.
Så tildele noen del av minnet.
Og hvor mange byte gjør vi faktisk ønsker å fordele, virker det?
>> Vel, strengen lengden på s.
Så hvis det er hallo det er kommer til å være fem.
Vi vil si h-e-l-l-o.
Så fem bytes.
>> Men så pluss en, hvorfor en?
Den 0 karakter.
Hvis vi ikke gir rom for denne fyren vi kunne tilfeldigvis skape en situasjon
hvor strengen er h-e-l-l-o.
Og så neste gang GetString er kalt og jeg skriver inn, for eksempel,
David, D-a-v-i-d, at maskinen kommer å tenke at s er faktisk
h-e-l-l-o-D-a-v-i-d fordi det er ingen pause i mellom disse ordene.
>> Så vi trenger det pause.
Så vi ønsker ikke fem.
Vi ønsker seks bytes.
>> Og bytes jeg si.
Men det er virkelig på tide størrelse på røye.
Teknisk røye er nesten alltid en enkelt byte.
>> Men bare for å gjøre vår kode bærbar, så å si, slik at det fungerer på
forskjellige datamaskiner selv om de kanskje være noe forskjellig under
hette, jeg kommer til generisk si størrelsen på røye, slik at
koden min alltid fungerer.
Og jeg trenger ikke å rekompilere det bare fordi jeg oppgradere min datamaskin eller bruke
noen annen plattform.
>> Så jeg har fått seks ganger størrelsen på en røye, som skjer for å være en.
Så det betyr malloc kunne gi meg seks bytes.
Hva er det egentlig gjør?
Vel, la meg rulle tilbake i tid her til der vi er i historien.
>> Så hvis jeg går tilbake hit, har jeg erklært en røye * heter t.
Jeg har nå kalt malloc for seks bytes.
Og nå skal jeg trekke de seks bytes akkurat som matrisen tidligere.
Men jeg faktisk ikke vet hva som er inne i denne matrisen.
>> Hvis du allokere minne det viser seg at du kan ikke stole på at det er noen
kjent verdi der.
Det kunne ha blitt brukt av noe annet, en annen funksjon, noen andre
linje med kode som du skrev.
Så får vi vanligvis kaller disse søppel verdier og tegne dem, kanskje, som
spørsmålstegn, bare indikerer at vi vet ikke hva som er faktisk der.
Og det er ingen big deal så lenge vi er smart nok til å overskrive de
søppel verdier med tall eller tegn på at vi bryr oss om.
>> Så i dette tilfellet hva skal jeg gjøre?
Vel, min linje av koden neste, jeg har fire.
int jeg får 0, får n hyssinglengde på s.
Så en kjent for loop.
I er mindre enn eller lik n, som vanligvis er over.
>> Men denne gangen er det bevisst.
I + +, og da jeg rett og slett gjøre t brakett jeg får s.
Fordi bildet mitt ser slik ut på dette øyeblikk, som er lagret i t er
Adressen til at tilfeldig mengde minne der verdiene er ukjent.
Men så snart jeg gjør t brakett 0 som setter meg her.
>> Og hva som ender opp med å bli trukket dit?
Vi ender opp med å sette h.
Fordi det er hva som står på s brakett 0.
Og deretter det samme for e, og L, og L, og o.
>> n, hvorfor jeg går opp gjennom en lik n?
På grunn av den 0 karakter.
Så bare for å være klar, da, hvis jeg faktisk fjerner alt disse søppel
verdier er og deretter faktisk trekke i hva jeg forventer, er dette s en brakett, 2,
3, 4, pluss det er etterfølgende ny karakter.
>> Og så nå hvis vi fortsatte forbi prikk, prikk, prikk i dette korrekt versjon
og aktiverte t brakett 0 jeg ville, av Selvfølgelig skal utnytte nettopp dette
fyren her, som konseptuelt, ble til slutt målet.
Så det er all pekeren er.
>> Og du har brukt dem i flere uker nå i forbindelse med strenger.
Men under panseret er de litt mer komplisert.
Men hvis du tenker på dem i denne billedlige formen jeg foreslå at de er
sannsynligvis ikke alle som skremmende som de kan først virke ved første øyekast,
spesielt med en slik ny syntaks.
Eventuelle spørsmål om pekere, strenger, eller chars?
Yeah?
>> PUBLIKUM: Kan du gå tilbake til [uhørlig]?
>> SPEAKER 1: Sure.
>> PUBLIKUM: Så hvordan kommer i din aller siste linje, trenger du ikke en * t linjen
og a * s i linjen?
Har du ikke referansen til -
>> SPEAKER 1: Ah, et virkelig godt spørsmål.
Hvorfor har jeg ikke en * t og a * s?
Fordi kort, forrige uke, som i vår swap funksjon, gjorde jeg si at når
du har fått en peker de midler som du går det som vi gjorde
fysisk på scenen, var å faktisk bruke stjernen operatør.
>> Det viser seg at denne plassen-brakett notasjon er hva vi kaller syntaktisk
sukker, som er bare en sexy måte sier det er korte notasjonen for
akkurat det du beskriver.
Men det er litt mer intuitivt.
Og med fare for å gjøre dette virke mer komplisert enn den trenger å være,
hva som egentlig skjer her er følgende -
Hvis jeg sier * t som betyr å gå til adressen som er lagret i t.
>> Så bokstavelig talt, hvis t er lagring adressen til denne h
utgangspunktet, * t betyr gå her.
Nå, hva t brakett 0 betyr?
Samme ting.
Det er bare litt mer brukervennlig vennlig å skrive.
>> Men jeg er ikke ferdig ennå.
Jeg kan ikke bare si * t får * s.
For hva ville jeg gjøre da?
Jeg vil være å sette h, h, h, h, h gjennom hele greia.
Høyre?
>> Fordi * t er å gå til adressen i t.
Men vi er inne i en løkke.
Og hvilken verdi jeg inkrementering, selvfølgelig på hver iterasjon?
jeg.
>> Men det er en mulighet her, ikke sant?
Selv om dette føles som det blir litt mer sofistikert
enn kvadrat-brakett notasjon vi har brukt på en stund -
la meg angre mitt h endring der -
selv om dette er nå å få litt mer avansert, den grunnleggende ideen, hvis * t
betyr her og * t er bare gå til adressen i t.
>> Men hva var adressen i t?
Tallet vi fortsette å bruke?
Som Ox456, la oss ta det tilbake bare for moro skyld for diskusjon.
Vel, hvis jeg ønsker å få på e i t streng, jeg bare ønsker å gå til,
hovedsak, 456.
>> Eller rettere sagt, 457.
Jeg trenger bare å legge en.
Men jeg kan gjøre det, ikke sant?
Fordi t, selv om jeg holder tegning det nå som en pil, det er bare en
nummer, Ox456.
Og hvis jeg legger man til det, eller mer generelt, hvis jeg legger jeg til at jeg kan
faktisk får akkurat der jeg vil.
Så hvis jeg faktisk gjør dette -
og dette er hva som nå kalles pekeren aritmetiske -
Jeg kan fjerne denne linjen.
Som er ærlig, tror jeg klarere og litt mer brukervennlig å lese.
Men dette er ikke mindre korrekt.
>> Dette kodelinje nå bruker pekeren aritmetikk.
Det sier gå til følgende adresse -
uansett starten av t er, hvilken er t pluss I, som i utgangspunktet
er 0, som er flott.
Fordi det betyr begynnelsen på t 1 pluss pluss 2, 3 pluss, og så videre.
Og samme avtale med s.
>> Så syntaktisk sukker for dette.
Men å forstå hva som egentlig skjer under panseret, vil jeg hevde,
faktisk er nyttig i seg selv.
Fordi det betyr at nå er det ikke mye mer magi skjer
under hetten.
Det kommer ikke til å være mange flere lag som vi kan skrelle tilbake etter deg.
Dette er ca.
Og dette er programmering.
Virkelig godt spørsmål.
>> Ok, så dette var at buggy programmet jeg refererte til tidligere.
swap var feil.
Hvis synes å fungere.
Husk at akkurat som med melk og appelsinjuice - som jeg startet
drikking dagens demonstrasjon.
Så akkurat som med appelsinjuice og melken, vi må bruke en
midlertidig variabel, tmp, for å holde en midlertidig slik at vi kunne da
endre sin verdi og deretter oppdatere b.
>> Men denne funksjonen, sa vi, eller dette program som denne funksjonen var
skrevet var galt og feil, hvorfor?
Ja?
>> PUBLIKUM: [uhørlig].
>> SPEAKER 1: Akkurat, da du kaller swap -
eller mer generelt, når du kalle de fleste noen funksjon -
hvis argumentene til at funksjonen er primitive, så å si, ints og chars
og dobbeltrom og flyter, ting uten stjerner, er du passerer i en kopi av
argumentet.
Så hvis x og y var en var 2, er en kommer å være en og b kommer til å være to.
Men de kommer til å være forskjellige biter av bits, ulike biter av
minne som tilfeldigvis lagring identiske verdier.
>> Så denne koden er super perfekt ved å bytte en og b.
Det er ikke bra i bytte -
i forrige ukes eksempel -
x og y.
Fordi igjen, de er i feil omfang.
>> Nå, hvordan vi går om å fikse dette?
Vi måtte gjøre funksjonen ser litt styggere.
Men igjen, vurdere hva Dette betyr bare.
>> Og faktisk, la meg, for konsistens, endre én ting, så det er identisk med
hva vi nettopp gjorde.
Som jeg nevnte i forrige uke, det gjør det ikke uansett hvor den går.
Faktisk, du vanligvis ville sette stjerne ved siden av variabelnavnet.
Men jeg tror det ville være litt lettere for å vurdere de * ved siden av
datatype som betyr at det er en peker til en int i dette tilfellet.
>> Så hva gjør jeg her?
Jeg sier ikke gi meg en int etterfulgt av en annen int,
kaller dem a og b.
Gi meg adressen til en int.
Gi meg adressen til en annen int.
Ring disse adressene a og b.
>> Og deretter bruke * notasjon ned nedenfor, kan du gå til hver av disse adressene
etter behov for å få enten eller angi verdien.
Men det er et unntak her.
Hvorfor har jeg ikke en * ved siden tmp?
Hvorfor gjør jeg ikke dette, for eksempel?
Det føles som om jeg skal bare gå alt ut og korrigere hele greia.
Yeah?
>> PUBLIKUM: [uhørlig].
>> SPEAKER 1: Jeg har ikke erklært tmp som en streng.
Så dette ville erklære, i dette tilfellet, en tmp å være adressen til en int.
Men det er ikke helt hva jeg vil, for et par grunner.
>> PUBLIKUM: Du ønsker ikke å bytte dem.
>> SPEAKER 1: Akkurat, jeg ønsker ikke å bytte noe med tmp. tmp er bare
uke-én ting.
Alt jeg ønsker er en variabel å lagre noen nummer.
Jeg vet ikke engang bryr seg om adresser i dette øyeblikk.
>> Jeg trenger bare 32 bits eller så å lagre en int.
Og jeg ønsker å sette i disse 32 bits hva er ikke i en, så å si, men
det som er ved en, bare for å være mer presis.
Fordi hvis en er en adresse, * et middel gå dit og få verdien 1.
For eksempel, i forrige ukes eksempel eller b sak, få verdien av to.
>> Så hva er det egentlig som skjer?
La meg tegne et bilde her som vil bare erte hverandre en del av i dag.
Men dette vil fortsette å dukke opp for en stund.
>> Dette, jeg hevder, er det datamaskinens minne ser ut når du kjører en
program, et program.
Når du kjører et program på toppen av datamaskinens RAM - så tenk på
dette rektangelet, virkelig, som din datamaskinens RAM eller minne, alt 101
milliard byte av det, alt to milliarder bytes, alle to gigabyte det,
uansett hvor mange du har er, la oss trekke det som et rektangel.
Og jeg hevder at når du kjører et program som Microsoft Word eller Chrome
eller noe sånt, de biter som Microsoft eller at Google skrev -
i tilfeller av disse programmene -
er lastet inn i datamaskinens minne hvor de kan utføres mer
raskt og matet inn i prosessoren, hvilken er hjernene av datamaskinen.
>> Og i TAM de er lagret i det toppen av programmet, så å si.
Med andre ord, hvis dette er en del av minne, når du dobbeltklikker på
Microsoft Word, bitene kommer av harddisken.
De blir lastet inn i RAM.
Og vi vil dytte dem opp på toppen av dette rektangelet konseptuelt.
>> Vel, er resten av minnet ditt brukes til forskjellige ting.
På toppen ser du initialisere data og uninitialize data.
Dette har å gjøre, for det meste, med konstanter eller globale variabler
som har verdier.
Men mer om dem en annen gang.
>> Da har du heap, som vi vil komme tilbake til.
Men på bunnen er den delen som er spesielt Germane akkurat nå.
Det er den såkalte stabelen.
Så akkurat som i de fleste noen D hall her på campus, har du de skuffene som
bare stables over hverandre på hvilken du kan sette mat og whatnot.
Stabelen i et datasystem er svært lik.
Unntatt mens skuffen, som vi bruker i matsalen, selvfølgelig, er ment
å bære ting magasinene eller rammene -
som vi kaller dem - i en datamaskins brukes til å holde
variabler og verdier.
>> Så hva går egentlig på under panseret?
Vel, la meg snu til skjermen her.
Og la oss fokusere bare på nederste delen for et øyeblikk.
Hvis dette er den nederste del av mine datamaskinens minne det viser seg når jeg
kaller funksjonen main - som skjer, ærlig,
automatisk for meg -
Jeg får en del av minnet på bunnen av RAM min så å si.
Og det er her viktigste er lokale variabler gå.
Det er der argc og argv kanskje gå, og eventuelle variabler I
erklære innsiden av main.
De ender opp på bunnen av datamaskinens RAM.
>> Nå antar at viktigste samtalene en funksjon som swap, som det gjorde i forrige uke?
Vel, vi i hovedsak sette en ny skuff, en ny ramme, på min del av minnet.
Og jeg kommer til å beskrive dette som tilhørighet til swap-funksjonen.
>> Nå hva som er inni swap?
Vel, basert på forrige ukes program og den vi nettopp så et utdrag fra,
innsiden av swap er ramme, eller på swap er skuffen, er hva variabler?
Vel, a og b.
Fordi de var de lokale argumenter, pluss en tredje, tmp.
Så egentlig kunne jeg trekke dette litt mer renslig.
La meg gå videre og angre på etiketten.
Og la meg si at du vet hva?
>> en er trolig kommer til å ende opp her.
B kommer til å ende opp her.
Og tmp kommer til å ende opp her.
Nå, de bestiller kanskje være litt annerledes.
Men konseptuelt dette er ideen.
>> Og bare kollektivt, dette er hva vi kaller swap er ramme, eller
spisesalen skuffen.
Og samme avtale med main.
Men jeg vil ikke tegne det.
Men det er der argc og argv og eventuelle av sine lokale variabler som x og y
kan være så godt.
>> Så nå vurdere hva som virkelig skjer når du ringer swap.
Når du ringer swap, gjennomføre kode som dette, er du passerer, i
buggy versjon, a og b som kopier av x og y.
Så hvis jeg nå trekke dette på skjermen -
må bli bedre på dette -
slik at historien jeg fortalte til meg selv var i denne buggy versjonen, når vi
ringe bytte passerer bokstavelig a og b som heltall, hva er det egentlig som skjer?
>> Vel, det som egentlig skjer er dette.
La meg gå videre og angre bare å rydde litt plass her.
Så dette er min datamaskinens minne.
>> Så hvis jeg har, for eksempel -
faktisk la oss gjøre det på denne måten -
hvis jeg påstår at dette er x, lagring verdien 1, akkurat som i forrige uke.
Og dette er y, lagring verdien 2 akkurat som forrige uke.
Og dette er det viktigste, når jeg ringer swap, og dermed gi meg selv tilgang til en og
b og tmp, kommer jeg til å hevde at Dette er en, og dette er en.
>> Dette er b.
Dette er to.
Dette kalles tmp.
>> Og i utgangspunktet, har det noen søppel verdi før jeg faktisk lagre i det,
som er 1.
Så jeg går videre og endre en å være det?
B verdi.
>> Og så nå har jeg to her.
Og da vi sa b får tmp.
Igjen, akkurat som en mental helse sjekk, den tredje kodelinje her er ganske enkelt dette
en, får b tmp.
>> Og så til slutt, hva gjør jeg?
Jeg går videre og endre b for å være hva verdien av TMP er, som er en.
Jeg vet ikke røre tmp igjen.
>> Men nå er problemet så snart som swap avkastning, fordi det ikke overlate
sikkerhetskopiere noen verdi, er det ingen vei tilbake uttalelse eksplisitt i den.
Hva er det som egentlig skjer?
Vel, egentlig alt dette minnet -
OK, tilsynelatende viskelær liker bare én finger om gangen -
bare forsvinner.
>> Nå i virkeligheten er det ikke noe sted.
Men du kan tenke på det nå som spørsmålstegn.
Fordi det er ikke lenger faktisk er i bruk.
Og ingenting blir gjort med disse verdiene.
>> Så i tilfelle av den grønne versjonen av denne koden, er det i stedet være
gått inn swap?
Så adresser.
Så adressen til x og adressen til y.
Så hvis vi re-fortelle denne historien en siste tid, og jeg faktisk trekke bytte igjen,
men med pekere, dette blir en, dette være b, og dette blir tmp, hva er
faktisk er lagret i en i denne grønne versjon av koden min der jeg har bestått
i-adresser?
>> Det kommer til å være en peker til x.
Så jeg kunne tegne en pil.
Men la oss bruke den samme vilkårlig eksempel som før.
La oss si at dette er noe som Ox123.
Og dette kommer til å være Ox127 fordi det er fire byte bort fordi det er en
int, så Ox127.
>> Og igjen, jeg tar noen friheter med tallene.
De er mye mindre enn de ville faktisk være og i en annen rekkefølge.
Men det er hvordan bildet Nå er annerledes.
>> Men når jeg bruker denne grønne koden og jeg får int tmp ikke * en.
* Et middel til å gjøre følgende, ta adressen som er i en og gå til det,
som er 1.
Og det er det jeg da satt i tmp.
I mellomtiden, i den neste linje med kode her, * en får b, hva betyr det?
>> Vel, * en, så gå her får * b, som betyr gå dit.
Og det betyr sette verdien til der.
Til slutt, den siste linje av koden bare sa * b får tmp.
>> Så b sier gå dit og overskrive den med tmp som, i dette tilfellet, går
å være igjen, en.
Og dette er grunnen til den grønne versjonen av våre koden fungerer, mens den røde
versjon aldri gjorde.
Det alle bare koker ned til hvordan minne styres og hvor det er
faktisk plasseres i datamaskinens RAM.
Og for nå, er at en av de tingene at stabelen blir brukt til.
>> Spørsmål om oppsettet?
På pekere?
Eller på swap?
>> Greit, så malloc, husker, gjorde noe sånt som dette.
Dette var en super enkelt eksempel.
Og dette var den som Binky introduserte oss til, om enn ganske
raskt, ved slutten av klasse.
Dammit, der vi går igjen.
>> Så husker at dette var et eksempel på at Binky introduserte oss til, om enn
noe raskere ved slutten av klasse.
Og her har vi brukt malloc virkelig for andre gang.
Fordi den første gang brukes det funnet å skape nok RAM, allokere nok RAM
å lagre en streng.
>> Denne gangen Binky holdt det enkelt.
Så det er å lagre bare en int, tilsynelatende.
Og det er helt greit.
Det er litt rart, ærlig, til bruke malloc å tildele en int.
Men poenget med Nick claymation var egentlig bare fortelle historien om hva
skjer eller ikke skjer når du mishandle minne.
>> Så i dette tilfelle dette programmet gjorde et par ting.
I det første tilfellet her, erklærer det en peker som heter x til en int.
Det erklærer deretter en peker kalt y til en int.
Den lagrer deretter i x, hva?
Noen andre nå.
Hva blir lagret i x henhold til den tredje linjen i dette programmet?
>> PUBLIKUM: [uhørlig].
>> SPEAKER 1: Vel, ikke helt bytes, per si.
Være mer presis nå.
Hva blir lagret i x?
En adresse, tror jeg jeg hørte det.
>> Så hva kommer ikke tilbake malloc?
malloc atferdsmessig tildeler en del av minnet.
Men hvordan gjør det gi deg tilgang til det?
Den returnerer hva?
Adressen til den første byte i mengde minne.
>> Nå, dette er super enkelt.
Det er bare én byte, noe som betyr at adressere vi får tilbake er
adressen til hele greia.
Så lagret i x da, er adressen av at mengde minne.
I mellomtiden, hva skjer videre?
Så egentlig, la oss gå videre og trekke dette ut virkelig rask.
>> Så hvis vi går over til skjermen her og vi spiller dette ut int * x og int * y
kommer til å gjøre det for meg?
Jeg hevder at det bare kommer til å gjøre noe som dette og kaller det x, og
dette og kaller det y.
I mellomtiden er den tredje linjen med kode kommer til å fordele på størrelse med en int,
som skjer for å være - beklager hvis jeg sa ett før jeg betydde en int -
fire byte på en vanlig datamaskin.
Minst med CS50 apparatet.
>> Så dette kommer til å allokere det, hvem vet?
Et eller annet sted her.
Og dette er lagret på et eller annet adresse Ox, hvem vet?
Men hva kommer til å bli returnert er denne adressen.
Men vi skal trekke dette pictorially som bare en pil sånn.
>> Nå i neste linje * x blir 42.
Hva * x betyr i lekmann vilkår?
Bare gå dit.
Gå til denne adressen.
Eller med andre ord, følg pil og sette 42 der.
Men så skjedde noe dårlig skjedde til Binky, ikke sant?
>> Husker at linje fem her, får * y 13, faktisk et uheldig tall,
gjorde det for oss?
Vel, * y del gå dit.
Vel, dette har ikke vært gitt en verdi ennå, ikke sant?
Koden trenger ikke være y initialisert til noe.
Vi hadde x initialiseres til en adresse.
Men y ble erklært opp toppen.
Men så et semikolon, ingen verdi ble faktisk satt i den.
Så det er rimelig å kalle dette en søppel verdi.
Hvem vet hva som er der?
Det er restene av biter som ble brukt ved noen tidligere linje med kode i
mitt program.
>> Så hvis jeg sier gå dit, dette er som, Jeg aner ikke hvor denne pilen er
kommer til å ende opp.
Og det er da du vanligvis få en segmentering feil.
Hvis du ved et uhell dereference, så å snakke, eller gå til en adresse som ikke er
faktisk en legitim adresse, dårlige ting skje.
>> Og det er akkurat hva som skjedde å tenke Binky.
Så husker at historien at Nick var forteller her var den samme ideen som hva
Jeg har tegnet med en illusjon av kritt på bordet der.
X og Y er deklarert.
>> Da vi tildelt størrelsen på en int og lagret den i x.
Så neste linjen vi gjorde * x.
Dette var nicks tryllestav av dereferencing.
Som satt 42 i minnet påpekt av x.
>> Men det er der ting gikk fryktelig galt.
Høyre?
Vi prøvde å dereference y.
Men y hadde noen falsk verdi, ikke sant?
>> At pilen nederst til venstre hjørne, er ikke
faktisk peker til noe.
Det er på en måte å gjøre det jeg gjorde her på brettet.
Så dårlige ting skje, segmentering skyld, eller Binky skyld, i dette tilfellet.
>> Men hvis vi da fikse det ved å gjøre x får y hvordan historien seg?
Vel, hvis jeg gjør x blir y, det er effektivt det samme som å si
hva dette er, Ox-noe kommer til å være det samme her,
Ox-noe.
Eller billedlig vi vil trekke en pil.
>> Så her på brettet med Binky, med den foregående linje i
koden, betyr * y gå dit.
Hvor er det?
Det betyr over her.
>> Og når vi oppdaterer den til å være 13 det innebærer bare går og
skriver 13 her nå.
Så kanskje ikke helt grei ved første øyekast.
Men for å oppsummere og å bruke samme sjargong at Binky var bruker her, så
de to første fordele pekere, x og y, men ikke de pointees.
Og pointees er ikke en vanligvis brukt begrep.
Men pekeren er absolutt.
Men det er hva som blir påpekt på i Binky sin nomenklatur.
>> Denne neste linje selvsagt tildeler en int pointee.
Så en del av minnet - som jeg trakk over på høyre side der - og sett
x lik peker på den.
Dette dereferences x for å lagre 42 i minnet at den peker på.
Og så dette, selvfølgelig, var en dårlig ting.
Fordi y ikke var peker på noe ennå.
Dette fikser det.
Så dette er fortsatt buggy program.
Bare fordi vi blåser gjennom koden linje for linje og si, oh well,
la det krasje der.
Det er en dårlig ting.
Odds er programmet bare kommer til å abortere helt på den linjen.
Men hvis du skulle fjerne krasjet Line og erstatte den med de to siste
linjer der du tilordner -
bruke pekeren oppdrag - y å peke på x som punkt t.
Og så dereference y på en svært sikker måte.
>> Så hvor etterlater dette oss?
Vel, det viser seg at under panseret i CS50 bibliotek, pekere er
brukt gjennom.
Og vi vil faktisk begynne å skrelle tilbake at lag før lenge.
Men det viser også et uttrykk som noen av dere kan bli kjent med,
spesielt de mer komfortable, er faktisk at av en meget populær
hjemmeside, eller stack overflow, disse dager.
>> Men dette har faktisk veldig tekniske betydning.
Vi vet nå hva en stabel er.
Det er som en bunke med skuffer innsiden av en spisesal.
>> Eller innsiden av datamaskinens minnet de rammer
som blir brukt av funksjoner.
Vel, det viser seg at på grunn av at meget enkel implementering av
hukommelse og rammene på såkalte stable, kan du faktisk ta kontroll
av et datamaskin-system ganske enkelt.
Du kan hacke seg inn i et system hvis folk som oss ikke har skrevet vår kode
spesielt godt.
>> Hvis folk liker oss bruke biter av minne eller bruk arrays -
enda oftere -
men noen ganger glemmer å kontrollere grenser matrise vår som du kanskje
har selv noen ganger, og iterated altfor langt forbi slutten en matrise.
I beste fall, ditt program kan bare krasje.
Segmentering feil, snill for pinlige.
Ikke stor, men det er ikke nødvendigvis en enormt dårlig ting.
>> Men hvis programmet er faktisk på ekte brukernes datamaskiner, hvis det kjører
på et nettsted som faktiske tilfeldige mennesker på internett er å treffe, slik at
folk indusere dårlige ting på koden din er generelt ikke en god ting fordi
det betyr en mulighet til å ta kontroll av datamaskinen.
Og dette kommer til å se litt kryptisk.
Men jeg tenkte jeg skulle skremme deg med Dette siste eksempelet her.
>> Her er et eksempel på kode.
Og det er en god Wikipedia artikkel som går gjennom
dette i mer detalj.
Jeg har main på bunnen kall foo, passerer i argv av en.
Og det er bare slik at du kan kjøre programmet og pass
en vilkårlig inngang.
>> Og så foo er erklært toppen som å akseptere en streng, eller mer
presist, en røye *.
Det erklærer deretter en rekke tegn.
Kall det en buffer, mer generelt, av størrelse 12.
Så 12 tegn kan passe inn av denne matrisen kalles c.
>> Og så den bruker den nye funksjonen, som er ny, men ikke vanskelig å
forstå, minne kopi.
Den kopierer minnet fra baren, som var den variable forbi n, uansett
brukeren har skrevet inn argv 1 inn c.
Hvor mange bytes?
Strengen lengde på bar.
>> Så med andre ord, hvis brukeren skriver inn h-e-l-l-o enter, strengen lengde
Hallo er fem.
Så fem av disse bytes kommer til å få kopiert inn i matrisen kalt c, som
er av størrelse 12.
Men hva brukeren skriver i en mye lengre ord som er 13 tegn eller 14
tegn eller 100 tegn eller mer?
>> Hvor de kommer til å gå?
Vel, det ramme, denne skuffen i spisesalen stack,
de kommer til å gå dit.
Og det er bare kommer til å begynne å overskrive andre ting som allerede er
på at bunken, overfylte bunken, så å si.
>> Så billedlig, tenk på det på denne måten.
Dette er bare en fargerik versjon av bildet vi har vært tegning.
Nederst, la oss si, er det viktigste.
Og på toppen, hva du ser nå blir rammen, fargekodet nå, for en
funksjon kalt foo.
Men det som er interessant her om foo er at her er rammen.
Så det er trukket akkurat som jeg gjorde, men i lys blå.
Og nå det er her c brakett 0 går.
Og det er her c brakett 11 kommer til å ende opp.
>> Med andre ord, det skjer representeres som en firkant.
Men hvis du bare holde plopping bytes ned - eller tegn - de kommer til å ende
0 opp ved sted hele veien opp til 11 fordi det er 0 indeksert.
>> Men hvor er det 13. tegnet kommer til å ende opp?
Hvor er den 14.?
Hvor er den 50. karakter kommer til å ende opp?
>> Det kommer til å holde det gående ned.
For selv om vi har trukket bilde med bunken vokser opp,
adresser, viser det seg, gå fra små adresser, liten
pekere, til store adresser.
Så det bare fortsetter å gå opp og opp.
>> Så hvis brukeren skriver inn hallo, det er flott.
Ingen bug, ikke noe problem, alle er trygt.
Men hvis brukeren skriver inn hva vi vil kaller motstandere kode, representert
generelt som en, angrep, angrep, angrep, angrep, hva kan skje?
>> Vel, hvis alle innspill som brukeren skrevet i er ikke bare noen vennlige
eller støtende streng med tegn.
Det er faktisk en sekvens av tegn at hvis du kompilert det,
det er faktisk kode.
Kanskje det er kode som sletter alle filer på harddisken din eller sender spam
eller noe sånt.
Legg merke til at det som er viktig her er at hvis skurken hadde flaks nok til å
overskrive den røde mengde minne -
som jeg ikke trekke på bildet mitt, men dette Wikipedia bildet her har -
sin såkalte returadresse.
>> Når mat avkastning, når swap returer, hvordan vet datamaskinen til å gå fra
her oppe til her nede?
Eller i tech segment opp ovenfor, hvor gjør det vet å gå fra swap
koden - det 0 og 1-ere som komponere swap -
tilbake til hovedsiden?
Det er en såkalt returadresse lagret i den samme stabel ramme, på
samme kafeteria skuffen.
>> Så hvis skurken er smart nok til å sette angrep kode, angrep kode, angrep
kode, og ha flaks nok -
ofte gjennom prøving og feiling - til overskrive den røde returadresse,
med adressen og innkalling helt til topps.
Legg merke 0835C080.
Det er skrevet baklengs opp toppen for grunnene til at vi vil kanskje revurdere.
Dette er det nummeret.
>> Så hvis slemmingen blir heldige nok eller er smart nok til å overskrive den røde
stripe av minne med adressen kode som han eller hun har en eller annen måte
injisert inn i datamaskinen, gjett som kode kommer til å bli returnert til
så snart foo blir gjort utføring?
>> The bad guy kode.
Så dette angrepet kode, AAA, igjen, kanskje sende spam, kan slette alle filene
på harddisken.
Men det er det virkelig en stack overflow er, eller en buffer overkjørt, eller en
buffer overflow angrep.
>> Og det er utrolig, utrolig vanlig til denne dagen med programmer skrevet i
C, C + +, og enda noen andre språk.
På den skremmende notatet, vil vi avslutte med en vits.
>> [Latter]
>> Ser deg på onsdag.
Ved neste CS50 -
Så jeg er alt ute av disk lamper i dag, men vente, fettfri melk, halvparten telefonen
bok, appelsinjuice at jeg drakk i dag.
USB-kabel, en skiftenøkkel.
>> [Musikk spilles]