[Powered by Google Translate] [Uke 5]
[David J. Malan - Harvard University]
[Dette er CS50. - CS50.TV]
>> Dette er CS50, uke 5.
I dag og denne uken introduserer vi en liten bit av verden av forensics
i sammenheng med problemet Set 4.
I dag vil være en forkortet foredrag fordi det er en spesiell hendelse her etterpå.
Så vi vil ta en titt og erte både elever og foreldre alike dag
med noen av de tingene som er på horisonten.
>> Blant dem, og med mandag, vil du ha noen flere klassekamerater.
EDX, Harvard og MIT nye online initiativ for OpenCourseWare og mer,
lanserer på Harvard campus på mandag, noe som betyr kommer mandag
du vil ha, som i forrige telling, 86000 flere klassekamerater
som skal følge sammen med CS50 foredrag og seksjoner
og gjennomgang og øvingsoppgaver.
Og som en del av dette, vil du bli medlemmer av innvielses klasse av CS50 og nå CS50x.
Som en del av dette nå, innser at det vil være noen oppsider også.
Å bli klar for dette, for det massive antall studenter,
nok det å si at selv om vi har 108 TFS og CAS,
det er ikke helt den beste student-lærer ratio når vi treffer 80.000 av elevene.
Vi kommer ikke til å bli gradering så mange problem setter manuelt,
så introdusert denne uken i oppgavesettet vil være CS50 Check,
som kommer til å være en kommandolinjeverktøy i apparatet
at du får når du oppdatere den senere denne helgen.
Du vil være i stand til å kjøre en kommando, check50, på din egen pset,
og du vil få umiddelbar tilbakemelding på om programmet er riktig eller feil
i henhold til ulike design spesifikasjoner som vi har gitt.
Mer om det i oppgavesettet spesifikasjonen.
De CS50x klassekamerater skal bruke dette også.
>> Problem Set 4 handler om dataanalyse,
og denne pset ble virkelig inspirert av noen virkelige ting
der da jeg var i gradsstudier jeg internert for en stund
med Middlesex County i statsadvokat kontor gjør rettsmedisin
med sin leder rettsmedisinske etterforsker.
Hva dette utgjorde, som jeg tror jeg har nevnt et par uker tidligere,
er massen State Police eller andre ville komme inn,
de ville slippe av ting som harddisker og CDer og disketter og lignende,
og deretter målet for etterforskning kontoret var å kartlegge
om det var eller ikke var bevis av noe slag.
Dette var den Special Investigations Unit, så det var økonomisk kriminalitet.
Det var mer problematisk slags forbrytelser, noe som involverer noen form for digitale medier.
Det viser seg at ikke så mange folk skrive en e-post som sier: "Jeg gjorde det."
Så ganske ofte, disse rettsmedisinske søk ikke skru opp så mye frukt,
men noen ganger folk ville skrive slike e-poster.
Så noen ganger, ble innsatsen belønnet.
>> Men å lede opp til dette rettsmedisinske pset, vil vi innføre i pset4 litt grafikk.
Du har sannsynligvis ta disse tingene for gitt - JPEG, GIF, og lignende - i disse dager.
Men hvis du virkelig tenker over det, et bilde, omtrent som Rob ansikt,
kunne bli modellert som en sekvens av punkter eller piksler.
I tilfelle av Rob ansikt, er det alle slags farger,
og vi begynte å se de enkelte punkter, ellers kjent som piksler,
når vi begynte å zoome inn
Men hvis vi forenkle verden litt og bare si at dette her er Rob i svart og hvitt,
å representere svart og hvitt, kan vi bare bruke binær.
Og hvis vi kommer til å bruke binære, 1 eller 0, kan vi uttrykke dette samme bildet
av Rob smilende ansikt med dette mønsteret av biter.
11000011 representerer hvitt, hvitt, svart, svart, svart, svart, hvit, hvit.
Og så det er ikke et stort sprang deretter å begynne å snakke om fargerike fotografier,
ting som du ville se på Facebook eller ta med et digitalt kamera.
Men sikkert når det kommer til farger, trenger du flere biter.
Og ganske vanlig i verden av fotografier er å bruke ikke 1-bit farge,
da dette antyder, men 24-bits farger, hvor du faktisk får millioner av farger.
Så som i tilfelle når vi zoomet inn på Rob øye,
det var en rekke av millioner av forskjellige fargerike muligheter.
Så vi vil innføre dette i oppgavesettet 4 samt i walkthrough,
som vil være i dag kl 03:30 i stedet for den vanlige 02:30 på grunn av fredagens foredrag her.
Men videoen vil være online som vanlig i morgen.
>> Vi vil også introdusere deg til et annet filformat.
Dette er bevisst ment å se skremmende i starten,
men dette er bare noen dokumentasjon for en C struct.
Det viser seg at Microsoft år siden hjalp popularisere dette formatet
kalt bitmap filformat, bmp, og dette var en super enkel, fargerik grafisk filformat
som ble brukt i lengre tid, og noen ganger fortsatt for bakgrunnsbilder på stasjonære maskiner.
Hvis du tenker tilbake til Windows XP og bølgende åser og den blå himmelen,
som var typisk en bmp eller punktgrafikkbilde.
Punktgrafikk er moro for oss fordi de har litt mer kompleksitet.
Det er ikke fullt så enkelt som dette rutenettet 0'er og 1'ere.
I stedet har du ting som en overskrift i begynnelsen av en fil.
Så med andre ord, inne i en. Bmp-fil er en hel haug med 0'er og 1'ere,
men det er litt ekstra 0'er og 1'ere der.
Og det viser seg at det vi har sikkert tatt for gitt i årevis -
filformater som. doc eller. xls eller. mp3,. mp4, uansett filformater
at du er kjent med - hva betyr det også bety å være et filformat,
fordi på slutten av dagen alle disse filene vi bruker har bare 0'er og 1'ere.
Og kanskje de 0'er og 1'ere representerer ABC gjennom ASCII eller lignende,
men på slutten av dagen, er det fortsatt bare 0'er og 1'ere.
Så mennesker bare sporadisk bestemmer seg for å oppfinne et nytt filformat
hvor de standardisere hva punktmønstre faktisk vil bety.
Og i dette tilfellet her, folk som designet bitmap filformat
sa at i det første byte i en bitmap fil, som vist ved offset 0 der,
det kommer til å være noen kryptisk navngitt variabel kalt bfType,
som bare står for bitmap filtype, hva slags bitmap fil er dette.
Du kan antyde kanskje fra andre rad som offset 2, byte nummer 2,
har et mønster av 0'er og 1'ere som representerer hva? Størrelsen på noe.
Og det går derfra.
Så i oppgavesettet 4, vil du bli gått gjennom noen av disse tingene.
Vi vil ikke ende opp å bry seg om dem alle.
Men merker det begynner å bli interessant rundt byte 54: rgbtBlue, grønn og rød.
Hvis du noen gang har hørt forkortelsen RGB - rød, grønn, blå - dette er en referanse til at
fordi det viser seg at du kan male alle farger i regnbuen
med en kombinasjon av rødt og blått og grønt.
Og faktisk, kan foreldrene i rommet husker noen av de tidligste projektorer.
I disse dager, du bare se én lys kommer ut av et objektiv,
men tilbake i dag hadde du den røde linse, blå linsen, og den grønne linse,
og sammen med sikte på en skjerm og dannet et fargerikt bilde.
Og ganske ofte, vil ungdomsskoler og videregående skoler har disse linsene
aldri så litt skjevt, så du var liksom se doble eller triple bilder.
Men det var ideen. Du hadde rød og grønn og blå lys male et bilde.
Og at samme prinsipp er benyttet i datamaskiner.
>> Så blant de utfordringene deretter for deg i oppgave Set 4 kommer til å være et par ting.
Det ene er å faktisk endre størrelsen på et bilde, for å ta i et mønster av 0'er og 1'ere,
finne ut hvilke biter av 0'er og 1'ere representerer det i en struktur som dette,
og deretter finne ut hvordan man kan gjenskape piksler - den røde, blues, greener -
innsiden, slik at når et bilde ser slik ut først,
det kan se slik ut i stedet etter det.
Blant de andre utfordringene for kommer til å være at du vil få utdelt en rettsmedisinsk bilde
av en faktisk fil fra et digitalt kamera.
Og på det kameraet, en gang i tiden var en hel haug med bilder.
Problemet er at vi ved et uhell slettet eller hadde bildet ødelagt eller annen måte.
Dårlige ting skjer med digitale kameraer.
Og så vi raskt kopiert alle 0'er og 1'ere ut av dette kortet for deg,
reddet dem alle i én stor fil, og vi vil overlate dem til deg i oppgave Set 4
slik at du kan skrive et program i C som å gjenopprette alle disse JPEG, ideelt.
Og det viser seg at JPEG, selv om de er litt av en kompleks filformat -
de er mye mer komplisert enn dette smilende ansikt her -
det viser seg at hver JPEG starter med de samme mønstre av 0'er og 1'ere.
Så bruker, til slutt, en stund loop eller en for løkke eller lignende,
du kan iterere over alle 0'er og 1'ere i denne rettsmedisinske bilde,
og hver gang du ser den spesielle mønster som er definert i oppgavesettet spesifikasjonen,
du kan anta her er, med svært høy sannsynlighet starten på en JPEG.
Og så snart du finner det samme mønsteret et antall byte
eller kilobytes eller megabyte senere, kan du anta her er en annen JPEG,
bildet jeg tok etter den første.
La meg slutte å lese den første filen, begynner å skrive denne nye,
og resultatet av programmet for pset4 kommer til å være så mange som 50 JPEG-bilder.
Og hvis det ikke er 50 JPEG-bilder, har du litt av en loop.
Hvis du har et uendelig antall JPEG, har du en uendelig loop.
Slik at også vil være ganske vanlig sak.
Så det er det som er på horisonten.
>> Quiz 0 bak oss, innser per e-posten min som alltid er det folk som er både glade,
slags nøytral, og trist rundt quiz 0 time.
Og vennligst nå ut til meg, hodet TF Zamyla, din egen TF,
eller en av de sertifikatutstedere som du vet om du ønsker å diskutere hvordan det gikk.
>> Så for å imponere foreldrene her i rommet, hva er CS50 biblioteket?
[Latter] God jobb.
Hva er CS50 biblioteket? Ja. >> [Student] Det er en pre-skrevet sett av koden [hørbar]
Ok, bra.
Det er en pre-skrevet sett med kode som vi ansatte skrev, vi gir til deg,
som gir noen felles funksjonalitet,
ting som får meg en streng, få meg en int - alle funksjoner som er oppført her.
>> Starter nå, begynner vi å virkelig ta disse trening hjul av.
Vi kommer til å begynne å ta bort en streng fra deg,
som tilbakekallingen var bare et synonym for hva som faktisk datatype? >> [Flere studenter] Char *.
Char *. For foreldre, var at sannsynligvis [gjør susende lyd]. Det er bra.
Char * vi vil begynne å se på skjermen hele mer som vi fjerner streng fra vårt vokabular,
i hvert fall når det gjelder å faktisk skrive kode.
Tilsvarende vil vi slutte å bruke noen av disse funksjonene så mye
fordi våre programmer kommer til å få mer sofistikert.
Snarere enn å bare skrive programmer som sitter der med en rask blinkende,
venter på at brukeren skriver noe i, vil du få innspill fra andre steder.
For eksempel, vil du få dem fra en rekke biter på den lokale harddisken.
Du vil i stedet få dem i fremtiden fra en nettverkstilkobling,
noen nettside eller annet sted.
>> Så la oss skrelle tilbake dette laget for første gang, og dra opp CS50 Appliance
og denne filen som heter cs50.h, som du har vært # inkludert i uker,
men la oss faktisk se hva som er på innsiden av dette.
Toppen av filen i blått er bare en hel haug med kommentarer:
garanti samt lisensiering.
Dette er liksom en felles paradigme i software
fordi mye av programvaren i disse dager er det som kalles åpen kildekode,
noe som betyr at noen har skrevet inn koden, og gjorde det fritt tilgjengelig
ikke bare å løpe og å bruke, men å faktisk lese og endre og integrere i ditt eget arbeid.
Så det er hva du har brukt, åpen kildekode, riktignok i en svært liten form.
Hvis jeg ruller nedover forbi kommentarene, men vil vi begynne å se noen mer kjente ting.
Varsel øverst her at cs50.h filen inneholder en hel haug med header filer.
De fleste av disse har vi ikke sett før, men man er kjent.
Hvilken av disse har vi sett, om enn kort, så langt? >> [Student] Standard biblioteket.
Ja, standard bibliotek. stdlib.h har malloc.
Når vi begynte å snakke om dynamisk minne allokering,
som vi vil komme tilbake til neste uke også, begynte vi med den filen.
Det viser seg at bool og sant og usant ikke egentlig eksisterer i C per se
med mindre du inkluderer denne filen her.
Vi har i flere uker vært inkludert stdbool.h
slik at du kan bruke tanken om en bool, sant eller usant.
Uten dette, ville du må sortere av falske det og bruke en int
og bare vilkårlig anta at 0 er falsk og en er sant.
Hvis vi blar ned ytterligere, her er vår definisjon av en streng.
Det viser seg, som vi har sagt før, at der denne stjernen er ikke virkelig betyr noe.
Du kan selv ha plass rundt.
Vi dette semesteret har vært fremme det som dette for å gjøre det klart
at stjernen har å gjøre med typen,
men innser like vanlig, om ikke litt mer vanlig,
er å sette det der, men funksjonelt er det det samme.
Men nå hvis vi leser ned ytterligere, la oss ta en titt på GetInt
fordi vi brukte som kanskje først før noe annet dette semesteret.
Her er GetInt. Dette er hva? >> [Student] En prototype. >> Dette er bare en prototype.
Ofte har vi satt prototyper på toppen av vår. C-filer,
men du kan også sette prototyper i header-filer,. h-filer, som dette her
slik at når du skrive noen funksjoner som du vil at andre skal kunne bruke,
som er nøyaktig tilfelle med CS50 biblioteket,
du ikke bare implementere dine funksjoner i noe som cs50.c,
du også sette prototypene ikke på toppen av filen, men på toppen av en header-fil.
Så at header-fil er hva venner og kolleger er
med # include i sin egen kode.
Så hele denne tiden, du har inkludert alle disse prototypene,
effektivt ved toppen av filen, men ved hjelp av denne # include mekanismen,
som i hovedsak kopierer og limer denne filen til din egen.
Her er noen ganske detaljert dokumentasjon.
Vi har ganske mye tatt for gitt at GetInt får en int,
men det viser seg at det er noen hjørne tilfeller.
Hva om brukeren skriver inn et tall som er altfor stor, en kvintillioner,
som bare ikke kan passe inn i en int? Hva er forventet oppførsel?
Ideelt sett er det forutsigbart.
Så i dette tilfellet, hvis du faktisk lese de fine print,
du faktisk se at hvis linjen ikke kan leses, dette returnerer INT_MAX.
Vi har aldri snakket om dette, men basert på kapitalisering sin, hva er det sannsynligvis?
[Student] En konstant. >> Det er en konstant.
Det er noen spesielle konstant som sannsynligvis erklært i en av disse header filer
det er høyere opp i filen, og INT_MAX er sannsynligvis noe sånt som omtrent 2 milliarder kroner,
ideen er at fordi vi trenger å liksom bety at noe gikk galt,
Vi, ja, har 4000 millioner tallene til rådighet: -2 milliarder opptil 2 milliarder kroner, gi eller ta.
Vel, hva er vanlig i programmering er du stjeler bare ett av disse tallene,
kanskje 0, kanskje 2 milliarder kroner, kanskje -2000000000,
slik at du tilbringer en av dine mulige verdier, slik at du kan forplikte seg til hele verden
at hvis noe går galt, vil jeg returnere denne super stor verdi.
Men du ikke vil at brukeren skrive noe kryptisk som 234 ..., en virkelig stort antall.
Du generaliserer den i stedet som en konstant.
Så egentlig, hvis du var å være anal de siste ukene, hver gang du ringte GetInt,
du burde ha vært sjekke med en hvis tilstanden gjorde brukeren skriver inn INT_MAX,
eller, mer spesifikt, gjorde GetInt retur INT_MAX, fordi hvis det gjorde,
som faktisk betyr at de ikke skriver det. Noe gikk galt i dette tilfellet.
Så dette er hva som vanligvis kjent som en sentinel verdi, noe som betyr bare spesiell.
>> La oss nå slå inn. C-fil.
C-filen har eksistert i apparatet i noen tid.
Og faktisk, har apparatet den pre-kompilert for deg inn at ting vi kalte objekt kode,
men det bare ikke noe for deg hvor det er fordi systemet vet
i dette tilfellet hvor det er: apparatet.
La oss bla ned nå for å GetInt og se hvordan GetInt har jobbet hele tiden.
Her har vi lignende kommentarer fra før.
La meg zoome inn på akkurat den koden delen.
Og hva vi har for GetInt er følgende.
Det tar ingen innspill.
Den returnerer en int, while (true), så vi har en bevisst uendelig løkke,
men antagelig vil vi bryte ut av dette liksom eller gå tilbake fra innenfor dette.
>> La oss se hvordan dette fungerer.
Vi synes å være å bruke GetString i denne første linjen inne i loopen, 166.
Dette er nå god praksis fordi under hvilke omstendigheter kunne GetString tilbake
den spesielle nøkkelord NULL? >> [Student] Hvis noe går galt.
Hvis noe går galt. Og hva som kan gå galt når du kaller noe som GetString?
Ja. >> [Student] malloc ikke klarer å gi det de ints.
Ja. Kanskje malloc mislykkes.
Somewhere under panseret, er GetString ringer malloc, som tildeler minne,
som lar datamaskinen butikken alle tegnene
at brukeren skriver inn i tastaturet.
Og anta at brukeren hadde en hel masse ledig tid og skrevet mer, for eksempel,
enn 2 milliarder tegn i, flere tegn enn datamaskinen har selv RAM.
GetString må være i stand til å betegne det til deg.
Selv om dette er en super, super uvanlig hjørne tilfellet
det må liksom være i stand til å håndtere dette,
og så GetString, hvis vi gikk tilbake og lese dokumentasjon, gjør faktisk avkastning NULL.
Så nå hvis GetString mislykkes ved å returnere NULL, er GetInt kommer til å mislykkes ved å returnere INT_MAX
akkurat som en vaktpost. Dette er bare menneskelige konvensjoner.
Den eneste måten du ville vite dette er tilfelle er ved å lese dokumentasjonen.
>> La oss bla ned til der int faktisk fått.
Hvis jeg ruller nedover et stykke, i tråd 170, har vi en kommentar ovenfor disse linjene.
Vi erklærer 172 en int, n, og en røye, c, og deretter denne nye funksjonen,
som noen av dere har snublet over før, sscanf.
Dette står for streng scanf.
Med andre ord, gi meg en streng og jeg vil skanne den for opplysninger av interesse.
Hva betyr det?
Anta at jeg skriver i, bokstavelig talt, 123 ved tastaturet og deretter trykke Enter.
Hva er datatypen for 123 da returnert av GetString? >> [Student] String.
Det er åpenbart en streng, ikke sant? Jeg fikk en streng.
Så 123 er virkelig, sitat-unquote, 123 med \ 0 på slutten av den.
Det er ikke en int. Det er ikke et tall. Det ser ut som et tall, men det er faktisk ikke.
Så hva har GetInt å gjøre?
Det har å skanne strengen venstre til høyre - 123 \ 0 - og noe konvertere til en faktisk heltall.
Du kan finne ut hvordan du gjør dette.
Hvis du tenker tilbake til pset2, du antagelig fått litt komfortabel med Caesar
eller Vigenere, slik at du kan iterere over en streng, kan du konvertere tegn til ints.
Men pokker, det er en hel masse arbeid.
Hvorfor ikke kalle en funksjon som sscanf som gjør det for deg?
Så sscanf forventer et argument - i dette tilfellet kalles linje, som er en streng.
Du kan deretter angi i anførselstegn, svært lik printf, hva du forventer å se i denne strengen.
Og hva jeg sier her er jeg forvente å se et desimaltall og kanskje et tegn.
Og vi vil se hvorfor dette er tilfellet i bare et øyeblikk.
Og det viser seg at denne notasjonen er nå minner om ting vi begynte å snakke om
litt over en uke siden.
Hva er & n og & c gjør for oss her? >> [Student] Adressen n og adresse på ca.
Ja. Det gir meg adressen til n og adresse c. Hvorfor er det viktig?
Du vet at med funksjoner i C, kan du alltid returnere en verdi eller ingen verdi i det hele tatt.
Du kan returnere en int, en streng, en flåte, en røye, uansett, eller du kan gå tilbake ugyldig,
men du kan bare gå tilbake én ting maksimalt.
Men her vi ønsker sscanf å returnere meg kanskje en int, et desimaltall,
og også en røye, og jeg skal forklare hvorfor røye i et øyeblikk.
Du effektivt vil sscanf å returnere to ting, men det er bare ikke mulig i C.
Du kan omgå det ved å sende inn to adresser
fordi så snart du hånden en funksjon to adresser,
hva kan denne funksjonen gjøre med dem? >> [Student] Skriv til disse adressene.
Det kan skrive til disse adressene.
Du kan bruke stjerne drift og gå dit, til hver av disse adressene.
Det er liksom dette bakdør mekanisme, men svært vanlig for å endre verdiene av variablene
mer enn bare ett sted - i dette tilfellet, to.
Nå merker jeg sjekker for == 1 og deretter retur n hvis det ikke faktisk vurdere å true.
Så hva er det som skjer? Teknisk sett er alt vi virkelig ønsker å skje i GetInt dette.
Vi ønsker å analysere, så å si, ønsker vi å lese strengen - sitat-unquote 123 -
og hvis det ser ut som det er en rekke det, hva vi forteller sscanf å gjøre
er satt som nummer - 123 - i denne variabelen n for meg.
Så hvorfor da fikk jeg faktisk har dette også?
Hva er rollen til sscanf sier du kan også få en karakter her?
[Uhørlig student respons] >> En desimaltegn faktisk kan fungere.
La oss holde det trodde et øyeblikk. Hva annet?
[Student] Det kan være NULL. >> God tanke. Det kan være null karakter.
Det er faktisk ikke i dette tilfellet. Ja. >> [Student] ASCII.
ASCII. Eller la meg generalisere ytterligere.
Den% c det er bare for feilsjekking.
Vi ønsker ikke at det skal være et tegn etter tallet,
men hva dette tillater meg å gjøre er følgende.
Det viser seg at sscanf, foruten lagring verdier i n og c i dette eksemplet her,
hva det også gjør er det returnerer antall variabler det satt verdier i.
Så hvis du bare skriver i 123, da bare% d kommer til å matche,
og bare n blir lagret med en verdi som 123,
og ingenting blir satt i ca.
C er fortsatt en søppel verdi, så å si -
søppel fordi den aldri har blitt initialisert til en viss verdi.
Så i dette tilfellet, returnerer sscanf 1 fordi jeg befolkede en av disse pekere,
i så fall flott, jeg har en int, så jeg frigjøre linjen for å frigjøre minne
at GetString faktisk tildelt, og da jeg kommer tilbake n,
annet hvis du noen gang lurt på hvor den Retry uttalelsen kommer fra, kommer det fra høyre her.
Så hvis, derimot, skriver jeg i 123foo - bare noen tilfeldige sekvens av tekst -
sscanf kommer til å se, antall, nummer, f,
og det kommer til å sette 123 i n, det kommer til å sette f i c og deretter gå tilbake to.
Så vi har, bare ved hjelp av grunnleggende definisjonen av sscanf oppførsel, en veldig enkel måte -
vel, komplekse ved første øyekast, men ved slutten av dagen ganske enkel mekanisme -
å si er det en int og hvis så, er at det eneste som jeg fant?
Og de tomme her er bevisst.
Hvis du leser dokumentasjonen for sscanf, forteller det deg at hvis du inkluderer et stykke blanktegn
på begynnelsen eller slutten, sscanf vil også tillate brukeren, uansett grunn,
å treffe space bar 123 og som vil være legitime.
Du vil ikke kjefte på brukeren bare fordi de treffer mellomromstasten
på begynnelsen eller slutten, som er bare litt mer brukervennlig.
>> Eventuelle spørsmål deretter på GetInt? Ja. >> [Student] Hva om du bare sette i en røye?
Godt spørsmål.
Hva om du nettopp skrev i en røye som f og trykk Enter uten å skrive 123?
Hva tror du oppførselen til denne linjen med kode vil da være?
[Uhørlig student respons]
Ja, så sscanf kan dekke det også fordi i så fall, er det ikke kommer til å fylle n eller c.
Det kommer til å i stedet returnere 0, og da er jeg også oppsiktsvekkende at scenario
fordi den forventede verdien jeg ønsker er en.
Jeg vil bare ha én og bare én ting å bli fylt. Godt spørsmål.
>> Andre? OK.
>> La oss ikke gå gjennom alle funksjonene i her,
men den som ser ut til å være kanskje av gjenværende interesse er GetString
fordi det viser seg at GetFloat, GetInt, GetDouble, GetLongLong
alle punt mye av sin funksjonalitet til GetString.
Så la oss ta en titt på hvordan han er implementert her.
Dette ser litt komplisert, men den bruker de samme grunnleggende
at vi begynte å snakke om forrige uke.
I GetString tar som ingen argument som per tomrommet opp her
og den returnerer en streng, jeg tydeligvis er erklære en streng som heter buffer.
Jeg vet egentlig ikke hva som kommer til å bli brukt til ennå, men vi får se.
Det ser ut som kapasiteten er som standard 0.
Ikke helt sikker på hvor dette går, ikke sikker på hva n kommer til å bli brukt til ennå,
men nå er det å få en litt mer interessant.
I tråd 243, erklærer vi en int, ca.
Dette er liksom en dum detalj.
En røye er 8 bits, og 8 bits kan lagre hvor mange ulike verdier? >> [Student] 256. >> 256.
Problemet er hvis du ønsker å ha 256 forskjellige ASCII-tegn, som det er
Hvis du tenker tilbake - og dette er ikke noe å huske.
Men hvis du tenker tilbake til den store ASCII diagrammet vi hadde uker siden,
Det var i så fall 128 eller 256 ASCII-tegn.
Vi brukte alle mønstre av 0'er og 1'ere opp.
Det er et problem hvis du ønsker å være i stand til å oppdage en feil
fordi hvis du allerede bruker 256 verdier for figurene dine,
du egentlig ikke har tenkt fremover fordi nå har du ingen måte å si,
dette er ikke en legit karakter, er dette noen feilaktige meldingen.
Så hva verden gjør er at de bruker den neste største verdien, noe som en int,
slik at du har en sprø antall biter, 32, for 4 milliard mulige verdier
slik at du kan bare ende opp med å bruke hovedsak 257 av dem,
1 som har noen spesiell betydning som en feil.
>> Så la oss se hvordan dette fungerer.
I tråd 246, har jeg denne store mens loop som ringer fgetc,
f mening fil, så getc, og deretter stdin.
Det viser seg at dette bare er mer presis måte å si lese inndata fra tastaturet.
Standard inngang betyr tastatur, betyr standard ut skjermen,
og standard feil, som vi vil se i pset4, betyr skjermen
men en spesiell del av skjermen, slik at det ikke er smeltet sammen med den faktiske produksjonen
at du hadde tenkt til å skrive ut. Men mer om det i fremtiden.
Så fgetc betyr bare lese ett tegn fra tastaturet og lagrer det der?
Oppbevar den i ca.
Og deretter sjekke - så jeg bare bruker noen Boolske konjunksjoner her -
sjekk at den ikke er lik - \ n, slik at brukeren har rammet inn, ønsker vi å stoppe på dette punktet,
slutten av loopen - og vi ønsker også å se etter den spesielle konstant EOF,
som hvis du vet eller antar, hva står for? >> [Student] Slutt på filen. >> Slutten av filen.
Dette er slags nonsens, fordi hvis jeg skriver på tastaturet,
det er egentlig ingen fil som er involvert i dette,
men dette er liksom bare av den generelle termen brukes til å bety
at ingenting annet kommer fra menneskelige fingre.
EOF - slutten av filen.
Som en side, hvis du noen gang har truffet Kontroll D på tastaturet, ikke at du ville ha ennå -
du har truffet Kontroll C - Control D sender denne spesielle konstant kalt EOF.
Så nå er det bare noen dynamisk minne allokering.
>> Så hvis (n + 1> kapasitet). Nå skal jeg forklare n.
N er bare hvor mange byte er for tiden i buffer,
strengen som du bygger opp fra brukeren.
Hvis du har flere tegn i buffer din enn du har kapasitet i buffer,
intuitivt hva vi trenger å gjøre da er tildele mer kapasitet.
Så jeg kommer til å skumme over noen av aritmetiske her og fokusere bare på denne funksjonen her.
Du vet hva malloc er eller er minst generelt kjent.
Ta en gjetning hva RealLOC gjør. >> [Student] Legger minne.
Det er ikke helt legge til minne. Det reallocates minne som følger.
Hvis det fortsatt er plass på slutten av strengen for å gi deg mer av det minne
enn det opprinnelig gir deg, så du får det ekstra minne.
Så du kan bare fortsette å sette strengen karakterer rygg mot rygg til rygg mot rygg.
Men hvis det ikke er tilfelle, fordi du ventet for lenge
og noe tilfeldig fikk plopped i minnet der
men det er ekstra minne her nede, det er greit.
RealLOC kommer til å gjøre alle de tunge løftene for deg,
flytte strengen du har lest i så langt herfra, legg det ned der,
og deretter gi deg litt mer rullebanen på det tidspunktet.
>> Så med en bølge av hånden, la meg si at det GetString gjør
er det å starte med en liten buffer, kanskje en enkelt karakter,
og hvis brukeren skriver inn to tegn, ender GetString opp med å kalle RealLOC og sier
ett tegn var ikke nok, gi meg to tegn.
Så hvis du leser gjennom logikken i loop, det kommer til å si
brukeren har skrevet i tre tegn, gi meg nå ikke 2, men 4 tegn,
så gi meg 8, og deretter gi meg 16 og 32.
Det faktum at jeg dobler kapasiteten hver gang
betyr at bufferen ikke kommer til å vokse sakte, det kommer til å vokse super fort.
Og hva som kan være fordelen av det?
Hvorfor jeg doble størrelsen på bufferen
selv om brukeren kan bare trenger én ekstra tegn på tastaturet?
[Uhørlig student respons] >> Hva er det? >> [Student] Du trenger ikke å dyrke den så ofte.
Akkurat. Du trenger ikke å dyrke den så ofte.
Og dette er bare slags du sikring dine spill her,
ideen er at du ikke ønsker å kalle RealLOC mye fordi det har en tendens til å være treg.
Hver gang du spør operativsystemet for hukommelse,
som du vil snart se i en fremtidig problem sett, pleier det å ta litt tid.
Så minimere den tiden, selv om du kaster bort litt plass,
tendens til å være en god ting.
>> Men hvis vi leser gjennom den avsluttende delen av GetString her -
og igjen forstå hver enkelt linje her er ikke så viktig i dag -
legge merke til at det til slutt kaller malloc igjen
og den fordeler akkurat som mange bytes som det er behov for streng
og kaster deretter bort ved å ringe gratis overdrevet store buffer
hvis det faktisk ble doblet for mange ganger.
Så kort sagt, det er hvordan GetString har jobbet hele tiden.
Alt den gjør er lest ett tegn om gangen igjen og igjen og igjen,
og hver gang det er behov for noen ekstra minne, spør den operativsystemet for det
ved å ringe RealLOC.
>> Eventuelle spørsmål? OK.
>> Et angrep.
Nå som vi forstår pekere eller i det minste blir stadig kjent med pekere,
la oss vurdere hvordan hele verden begynner å kollapse
Hvis du ikke helt forsvare seg mot fiendtlige brukere,
folk som prøver å hacke seg inn i systemet ditt,
folk som prøver å stjele programvare ved å omgå noen registreringskode
at de kanskje ellers å skrive i.
>> Ta en titt på dette eksempelet her, som er bare C-kode som har en funksjon viktigste nederst
som kaller en funksjon foo. Og hva er det passerer til foo?
[Student] Et enkelt argument. >> [Malan] En enkelt argument.
Så argv [1], som betyr det første ordet som brukeren har skrevet på kommandolinjen
etter a.out eller hva programmet heter.
Så Foo på toppen tar i en char *. Men char * er akkurat hva? >> [Student] En streng.
[Malan] En streng, så det er ikke noe nytt her.
Strengen er vilkårlig å bli kalt bar.
I denne linjen her, røye c [12], i form av semi-teknisk engelsk, hva denne linjen gjør?
[Student] En rekke - >> Array av? >> [Student] tegn. >> Tegn.
Gi meg en rekke 12 tegn. Så vi kan kalle dette en buffer.
Det er teknisk kalt c, men en buffer i programmering betyr bare en haug med plass
at du kan sette noen ting i.
Så til slutt, memcpy vi ikke har brukt før, men du kan sikkert gjette hva det gjør.
Det kopierer minnet. Hva gjør den?
Det tilsynelatende kopierer bar, sin inngang, i c, men bare opp til lengden på baren.
Men det er en feil her. >> [Student] Du trenger sizeof karakter. >> Ok.
Teknisk sett bør vi egentlig gjøre strlen (bar) * sizeof (char)). Det er riktig.
Men i verste tilfelle her, la oss anta at that -
Okay. Så er det to bugs.
Så sizeof (char));
La oss gjøre dette litt bredere.
Så nå er det fortsatt en bug, som er hva? >> [Uhørlig student respons]
Sjekk for hva? >> [Student] Sjekk for NULL.
Vi bør generelt være sjekker for NULL fordi dårlige ting skjer
når pekeren er NULL fordi du kan ende opp med å gå der,
og du ikke skulle gå til NULL ved dereferencing det med stjernen operatør.
Så det er bra. Og hva annet gjør vi? Logisk, det er en feil her også.
[Student] Sjekk om argc er> = til 2.
Så sjekk om argc er> = 2. Ok, så det er tre feil i dette programmet her.
Vi overvåker nå sjekke om brukeren faktisk skrevet i noe inn argv [1]. Bra.
Så hva er den tredje bug? Ja. >> [Student] C er kanskje ikke stor nok.
Bra. Vi sjekket ett scenario.
Vi implisitt sjekket ikke kopier mer minne enn det som ville overskride lengden bar.
Så hvis strengen brukeren skrev inn er 10 tegn lang,
dette sier bare kopiere 10 tegn. Og det er greit.
Men hva om brukeren har skrevet inn et ord når du får beskjeden som en 20-tegns ord?
Dette sier kopien 20 tegn fra bar til hva?
C, ellers kjent som buffer vår, noe som betyr at du nettopp skrev data
til 8 byte steder som du ikke eier,
og du ikke eier dem i den forstand at du aldri tildelt dem.
Så dette er hva som vanligvis kjent som buffer overflow angrep eller bufferoverløp angrep.
Og det er et angrep i den forstand at hvis brukeren eller programmet som ringer din funksjon
gjør dette skadelig, hva som faktisk skjer neste kan faktisk være ganske dårlig.
>> Så la oss ta en titt på dette bildet her.
Dette bildet representerer bunke med minne.
Husker at hver gang du ringer en funksjon du får denne lille rammen på stakken
og deretter en annen og deretter en annen og en annen.
Og så langt, har vi bare slags abstrahert disse som rektangler
enten på styret eller på skjermen her.
Men hvis vi zoomer inn på en av disse rektangler, når du ringer en funksjon foo,
det viser seg at det er mer på stakken innsiden av rammen i at rektangelet
enn bare x-og y-og a og b, som vi gjorde snakker om swap.
Det viser seg at det er noen lavere nivå detaljer, blant dem Returadresse.
Så det viser seg når main kaller foo, har viktigste å informere Foo
hva main adresse er i datamaskinens minne
fordi ellers er så snart Foo gjort utfører, som i dette tilfelle her,
Når du når dette lukkede krøllete brace på slutten av foo,
hvordan pokker vet foo hvor kontrollen av programmet er ment å gå?
Det viser seg at svaret på det spørsmålet er i denne røde rektangelet her.
Dette representerer en peker, og det er opp til datamaskinen for å lagre midlertidig
på den såkalte stabel adressen main slik at så snart Foo gjøres utfører,
maskinen vet hvor og hvilken linje i hoved å gå tilbake til.
Lagret Ramme pekeren vedrører tilsvarende til dette.
Char * bar her representerer hva?
Nå er dette blå segmentet er her Foo ramme. Hva er bar?
Baren er bare argumentet til foo funksjonen.
Så nå er vi tilbake på liksom den kjente bildet.
Det er flere ting og flere distraksjoner på skjermen,
men dette lyseblå segmentet er akkurat hva vi har å tegne på tavlen
for noe sånt swap. Det er rammen for foo.
Og det eneste i det akkurat nå er bar, som er denne parameteren.
Men hva annet bør være i bunken i henhold til denne koden her?
[Student] char c [12]. >> [Malan] char c [12].
Vi bør også se 12 ruter minne som er tildelt en variabel kalt c,
og faktisk vi ikke har det på skjermen.
Helt øverst er det c [0], og deretter forfatteren av dette diagrammet
ikke bry tegne alle rutene, men det er faktisk 12 der
fordi hvis du ser nederst til høyre, c [11] hvis du teller fra 0 er den 12. slik byte.
Men her er problemet.
I hvilken retning er c vokser?
Sortering av toppen og ned hvis det begynner på toppen og vokser til bunnen.
Det ser ikke ut som vi forlot oss mye rullebane her i det hele tatt.
Vi har slags malt oss inn i et hjørne,
og at c [11] er helt opp mot bar, som ligger rett opp mot Lagret Frame pekeren,
som er rett opp mot Returadresse. Det er ikke mer plass.
Så hva er konsekvensen så hvis du skru opp
og du prøver å lese 20 bytes i en 12-byte buffer?
Hvor er de åtte flere byte kommer til å gå? >> [Student] Inside -
Inne alt annet, er noen av dem super viktig.
Og det viktigste, potensielt, er den røde boksen der, Returadresse,
fordi anta at du enten ved et uhell eller adversarially overskrive de 4 bytes,
at pekeren adresse, ikke bare med søppel, men med et antall
som skjer for å representere en faktisk adresse i minnet.
Hva er konsekvensen, logisk? >> [Student] Funksjon kommer til å gå tilbake til et annet sted.
Akkurat.
Når foo avkastning og treff som krøllete brace, er programmet kommer til å fortsette
ikke å gå tilbake til hovedsiden, kommer det til å gå tilbake til hva adressen er i det røde boksen.
>> I tilfelle av omgå programvare registrering,
hva hvis adressen som blir returnert til er den funksjonen som normalt blir kalt
etter at du har betalt for programvaren og lagt inn din registreringskode?
Du kan liksom lure datamaskinen i å ikke gå her, men i stedet kommer opp her.
Eller hvis du er virkelig flink, kan en motstander faktisk skrive på tastaturet, for eksempel,
ikke en faktisk ord, ikke 20 tegn, men antar han eller hun faktisk typer i
enkelte tegn som representerer koden.
Og det kommer ikke til å være C-kode, er det faktisk kommer til å være tegn
som representerer binær maskinkode, 0'er og 1'ere.
Men antar de er smarte nok til å gjøre det,
å liksom lime inn i GetString rask noe som er egentlig kompilert kode,
og de siste 4 byte overskrive returadresse.
Og hva adressen ikke at innspill gjøre?
Den lagrer faktisk i denne røde rektangelet adressen til den første byte i buffer.
Så du må være veldig flink, og dette er en mye prøving og feiling for dårlige mennesker der ute,
men hvis du kan finne ut hvor stor denne bufferen er
slik at de siste få byte i inngangen du gir til programmet
skje for å være tilsvarende adressen til starten av bufferen, kan du gjøre dette.
Hvis vi sier normalt hei og \ 0, er at hva som ender opp i bufferen.
Men hvis vi er mer smart og fylle vi at buffer med hva vi vil generelt kaller angrep kode -
AAA, angrep, angrep, angrep - der dette er bare noe som gjør noe dårlig,
hva skjer hvis du er virkelig flink, kan du gjøre dette.
I den røde boksen her er en sekvens av tall - 80, C0, 35, 08.
Legg merke til at det samsvarer med tall som er her oppe.
Det er i motsatt rekkefølge, men mer om det en annen gang.
Legg merke til at denne avkastningen adressen er bevisst endret
til lik adresse her oppe, ikke adressen til main.
Så hvis skurken er super smart, er han eller hun kommer til å inkludere i det angrepet kode
noe som sletter alle brukerens filer eller kopiere passord
eller opprette en brukerkonto som jeg kan deretter logge deg på - noe som helst.
>> Og dette er både faren og kraften i C.
Fordi du har tilgang til minnet via pekere
og du kan derfor skrive alt du vil inn i datamaskinens minne,
du kan gjøre en datamaskin gjøre hva du vil
bare ved å ha den til å hoppe rundt i sin egen plass i minnet.
Og så til denne dagen så mange programmer og så mange nettsteder som er kompromittert
koke ned til folk som tar seg av dette.
Og dette kan virke som en super sofistikert angrep, men det er ikke alltid starte på den måten.
Realiteten er at det dårlige mennesker vil vanligvis gjør er,
enten det er et program på en kommandolinje eller et GUI-program eller et nettsted,
du bare begynne å tilby tull.
Du skriver i en virkelig store ord i søkefeltet og trykke Enter,
og du vente å se om nettstedet krasjer
eller du vente å se om programmet manifesterer noen feilmelding
fordi hvis du får heldig som skurken og du gi noen sprø innspill
som krasjer programmet, som betyr at programmereren ikke forutse din dårlig oppførsel,
som betyr at du kan sannsynligvis med nok innsats, nok prøving og feiling,
finne ut hvordan å føre en mer presis angrep.
Så like mye en del av sikkerhet er ikke bare å unngå disse angrepene helt
men registrerer dem og faktisk ser på loggene
og se hva gale innganger har folk skrevet inn i din webside,
hvilke ord har folk skrevet inn i din webside
i håp om overfylte noen buffer.
Og alt dette koker ned til det enkle grunnleggende for hva som er en matrise
og hva betyr det å allokere og bruke minne.
>> Relatert til dette så altfor er dette.
La oss bare se innsiden av en harddisk enda en gang.
Du husker fra en uke eller to siden at når du drar filer til papirkurven eller papirkurven kan,
hva skjer? >> [Student] Ingenting. >> Absolutt ingenting, ikke sant?
Slutt hvis du kjører lite diskplass,
Windows eller Mac OS vil begynne å slette filene for deg.
Men hvis du drar noe der inne, er det ikke i det hele tatt trygt.
All din samboer eller venn eller et familiemedlem har å gjøre er å klikke dobbelt, og voila,
det er alle de sketchy filer som du prøvde å slette.
De fleste av oss i det minste vite at du må høyreklikke eller Kontroll-klikk
og tømme papirkurven eller noe sånt.
Men selv da det ikke gjøre ganske triks
fordi hva som skjer når du har en fil på harddisken din
som representerer noen Word-dokument eller noen JPEG, og dette representerer harddisken din,
og la oss si at dette sliver her representerer den filen,
og det er sammensatt av en hel haug med 0'er og 1'ere.
Hva skjer når du ikke bare dra filen til papirkurven kan eller resirkulere bin
men også tømme den? Sortering av ingenting.
Det er ikke absolutt ingenting nå.
Nå er det bare ingenting fordi en liten noe skjer i form av denne tabellen.
Så det er en slags database eller tabell på innsiden av en datamaskin minne
som har vesentlig én kolonne for filer navn og en kolonne for filer 'plassering,
hvor dette kan være plassering 123, bare et tilfeldig nummer.
Så vi kan ha noe som x.jpeg og plassering 123.
Hva skjer så når du faktisk tømme papirkurven?
Det går unna.
Men hva går ikke bort er 0'er og 1'ere.
>> Så hva er da forbindelsen til pset4?
Vel, med pset4, bare fordi vi har et uhell slettet compact flash-kort
som hadde alle disse bildene, eller bare fordi det ved uflaks ble ødelagt
betyr ikke at 0'er og 1'ere er ikke der ennå.
Kanskje noen av dem er tapt fordi noe ble ødelagt
i den forstand at noen 0s ble 1s og 1'ere ble 0s.
Dårlige ting kan skje på grunn av buggy programvare eller defekt maskinvare.
Men mange av disse bitene, kanskje 100% av dem, er der fremdeles.
Det er bare det at datamaskinen eller kameraet ikke vet hvor JPEG1 startet
og hvor JPEG2 startet.
Men hvis du, programmerer, vet med litt peiling hvor disse JPEG er
eller hvordan de ser ut, slik at du kan analysere 0'er og 1'ere og si JPEG, JPEG,
Du kan skrive et program med egentlig bare en for eller mens loop
som gjenoppretter hver og en av disse filene.
Så lærdommen er da å begynne sikkert slette filene dine
Hvis du ønsker å unngå dette helt. Ja.
>> [Student] Hvordan kommer det står på din datamaskin
at du har mer minne enn du gjorde før?
Ha mer minne enn du gjorde før - >> [student] Mer tilgjengelig minne.
Oh. Godt spørsmål.
Så hvorfor da etter tømming av søppel forteller datamaskinen du
at du har mer ledig plass enn du gjorde før?
I et nøtteskall, fordi det lyver.
Mer teknisk, har du mer plass fordi du nå har sagt
du kan sette andre ting der filen en gang var.
Men det betyr ikke at de biter går bort,
og det betyr ikke at bitene blir endret til alle 0s, for eksempel,
for å beskytte deg.
Så derimot, hvis du sikkert slette filer eller fysisk ødelegge enheten,
det er virkelig den eneste måten noen ganger rundt det.
>> Så hvorfor ikke vi la på at semi-skremmende notat, og vi vil se deg på mandag.
[Applaus]
>> [CS50.TV]