[MUSIC JOC]
>> David J. MALAN: Bine.
Acest lucru este CS50.
Și acesta este începutul de săptămână 5.
Și, după cum poate ați observat, o parte din materialul
devine un pic mai mult complex, puțin densă.
>> Și este foarte ușor, mai ales dacă ai fost în obiceiul de ceva timp,
să încerce să mâzgălească jos cele mai orice am face, ne spune în clasă.
Dar dau seama, că nu este, probabil, abordarea ideală pedagogic
pentru a învăța acest tip de material, și mai mult material, în general.
Și așa suntem încântați să anunta propria Gheng că CS50 lui
Gong a început să se pregătească un set canonic de note
pentru curs, speranța de și anume că, unul, acestea
servi nu numai ca un referință și o resursă
pentru revizuirea materialelor și merge înapoi prin materiale care ar putea avea
ai scăpat prima dată în jurul, dar De asemenea, astfel încât capetele pot fi mai
în sus decât în ​​jos, atunci când vine vorba de timp pentru a preda,
astfel încât s-ar putea angaja mai gânditor, ca
Spre deosebire de mai scribbly.
>> Cu care a spus, ceea ce veți găsi pe site-ul este de documente, cum ar fi acest lucru.
Și preaviz, la stânga sus, nu e nu doar un cuprins,
dar, de asemenea, codurile de timp care vă va sari imediat
la partea corespunzătoare în video online.
Și ce Chang aici a făcut este, în esență, documentate
ceea ce sa întâmplat în acest special prelegere.
Și mulți dintre cursurile sunt deja on-line acum cu acest URL.
Și vom continua să posta restul a celor de la sfârșitul acestei săptămâni,
asa ca profita de această resursă.
>> Deci, fără alte formalități, am început să coaja înapoi
stratul care a fost șir de ceva timp.
Și ceea ce am spus un șir este de fapt săptămâna trecută?
Stele Deci, char.
Și stea char, bine, ce am de fapt acest lucru?
Ei bine, în tot acest timp, în cazul în care ne-am sunat o funcție,
ca getString, și depozitare așa-numitul revenirea
Valoarea de getString într-o variable-- se numește
s tip string-- am scris linie de cod acolo sus.
Și e doar atunci când văd meu scris de mână amplificat aici
îmi dau seama cât de atroce este.
>> Cu toate acestea, să presupunem că, pe partea dreaptă
este, totuși, un rezonabil descriere a ceea ce este
se intampla toate astea timp cu getString.
getString, desigur, devine un șir.
Dar ce înseamnă de fapt acest lucru?
Aceasta înseamnă că devine o bucată de memorie din sistemul de operare
prin apelarea unei funcții, numită malloc.
Dar mai multe despre asta mai târziu.
Și apoi populează că bucata de memorie
cu literele utilizatorul are introduce, urmată de, desigur,
un caracter nul, sau backslash zero la sfârșit.
>> Între timp, pe partea stângă din această poveste, în tot acest timp,
am fost declararea unei variabile, cum ar fi s.
Și că variabila este ceea ce acum va începe de asteptare un pointer.
Nu este o cutie interior de care am pus șir, Daven, în sine,
ci mai degrabă ne-am pus în pătrat caseta din stânga a ce anume?
Da?
>> Audiența: Adresa de în cazul în care se află în memorie.
>> David J. MALAN: Exact.
Adresa de unde Daven este localizat în memorie.
Și nu în cazul în care toate de Daven se află, în sine, dar în mod special adresa
de ce?
Da?
>> Audiența: Primul caracter.
>> David J. MALAN: Primul caracter în Daven, care, în acest caz,
Am propus a fost arbitrar și nerealist 1, OX1,
care înseamnă doar număr hexazecimal de 1.
Dar este, probabil, va să fie un număr mult mai mare
pe care le-ar putea atrage cu un 0x ca prefix,
reprezentând un caracter hexazecimal.
Și pentru că nu avem nevoie să știm unde restul personajelor de Daven
sunt, pentru că de ce design simplu decizie care a fost făcut în urmă cu mai mulți ani?
Da?
>> Audiența: Backslash 0.
David J. MALAN: Da, exact.
Backslash 0 va permite, chiar dacă în timp liniar, pentru a traversa șir,
de mers pe jos de la stânga la dreapta, cu o buclă de, sau un timp
buclă, sau ceva de genul că, și de a determina, oh, aici
este sfârșitul acestui șir particular.
Deci, cu doar adresa la începutul unui șir,
putem accesa totalitatea ea, pentru că în tot acest timp,
un șir a fost doar o stea char.
>> Deci, este cu siguranță bine pentru a continua utilizarea biblioteca CS50 și această abstracție,
ca să spunem așa, dar vom începem să vedem exact
ceea ce se întâmplă sub tot acest timp.
Deci, s-ar putea aminti acest exemplu, de asemenea, de la ultima dată, compara 0,
care nu au efectiv compara.
Dar am început să rezolve acest lucru.
>> Dar, așa cum, probabil, o perfecționare, s-ar putea să intereseze pe cineva
într-un elefant roz de astăzi, de asemenea, făcută de Chang?
Cum despre tine in fata? [Neauzit].
Hai sus.
>> Și între timp, cum ți-a venit, să
ia în considerare pentru o clipă ce acest cod a fost de fapt fac.
Este declararea de două variabile în sus top, s și t, și de asteptare getString.
Acesta nu este un program foarte user-friendly, pentru că nu-ți spun ce să facă.
Dar să presupunem că suntem concentrându-se pe de o parte suculent.
Și atunci ce facem, în cazul în care s este egal cu este egal cu t, ar trebui să spunem printf,
ați tastat același lucru.
Buna ziua.
Care e numele tău?
>> Janelle: Janelle.
David J. MALAN: Janelle, bucur să te cunosc.
Deci, provocarea la mână pentru acest elefant
este de a atrage noi mai întâi o imagine a ceea ce este fiind reprezentată în cele două întâi
linii.
Deci s și t poate fi a reprezentat modul de pe ecran?
Și tu poți să-l trage cu degetul pe acest ecran mare.
>> Deci, există două jumătăți de fiecare parte a acestei ecuații.
Deci, există e pe stânga, și apoi getString pe dreapta.
Și apoi există t pe partea stângă, și apoi getString pe dreapta.
Deci, cum s-ar putea să începem desen o imagine care
reprezintă ceea ce se întâmplă aici în memorie, ai spune?
Și lasă-mă să vă explic ce faci ca te duci.
>> Janelle: OK.
Ei bine, în primul rând, s-ar fi cerut tine pentru a obține șirul de intrare.
Și s-ar store-- oh, îmi pare rău.
David J. MALAN: OK.
Bun.
Și aceasta se numește ce?
Oh, OK.
Continuă.
N-am vrut să vă întrerup.
Janelle: Îmi pare rău.
Deci, ar fi de intrare in adresa nu de-- sigur.
Nu-mi amintesc exact numărul, dar eu cred că a fost, începând cu 0.
>> David J. MALAN: Nu-i nimic, pentru că am făcut numerele sus,
astfel încât nu există nici un răspuns corect.
>> Janelle: Începând cu 0 arcul.
>> David J. MALAN: OK, deci element de 0.
Sigur.
>> Janelle: Și apoi, dacă a fost ca doar un doi-cu scrisoarea
>> David J. MALAN: OK, înapoi la tine.
>> Janelle: Deci element de 0, și apoi elementul 1 sau element de 2.
David J. MALAN: Si care bucată de imaginea desenezi chiar acum?
Apelul la getString?
Sau declarația de s?
>> Janelle: Declarația de s, cred.
Oh, getString, deoarece aceasta ar să fie introduse în fiecare [? domeniu. ?]
>> David J. MALAN: Bine.
Exact.
Chiar dacă acest lucru în mod eficient returnează o matrice, rechemare,
când ne întoarcem un șir, putem index în care string, folosind 01 și 2.
Punct de vedere tehnic, acestea sunt, probabil, reprezentată de adrese individuale,
dar asta e bine.
>> Deci, să presupunem că, dacă pot doar rapid transmite de unde am ramas
ultima dată, în cazul în care unul dintre siruri de caractere a fost g o b e,
backslash 0, reprezentând astfel lui Gabe de intrare, cum s-ar putea să ne reprezentăm e acum?
Dacă aceasta este memoria care este fost returnate de către getString?
>> Janelle: Ar fi reprezentat de un arc?
>> David J. MALAN: Printr-un arc?
Ei bine, nu.
Să spunem doar că, pictural, lasă-mă să merg mai departe
și propune ca, în cazul în care acest lucru este s, această este valoarea de returnare a getString.
Și ai tras aceasta ca 0, 1, 2, care este perfect rezonabil, pentru că ne-am
poate indexa în șir, ca atare.
Dar, doar pentru a fi în concordanță cu Ultima dată, lasă-mă să merg mai departe
și propune în mod arbitrar că această este adresa 1, aceasta este adresa 2,
aceasta este adresa 3, și așa mai departe.
Și așa, doar pentru a fi super clar, ce se întâmplă
pentru a merge într-s ca un rezultat de care prima linie de cod, ai spune?
>> Janelle: Adresa 1?
>> David J. MALAN: Exact.
Deci, adresa 0x1.
Și între timp, lasă-mă să mergeți mai departe și duplicat de mult de ceea ce ai făcut
și adăugați propria mea t aici.
Dacă ar fi să tastați în Gabe din nou, a doua oară,
când vi se solicită cu getString, în cazul în care, desigur, este Gabe va merge?
Ei bine, presumably--
>> Janelle: Ca pe aici?
David J. MALAN: Da.
Janelle: Sau este, de asemenea, în aceleași cutii?
David J. MALAN: Lasă-mă să propună, da, exact, deci în aceste cutii suplimentare.
Dar ceea ce este esențial acum este că, chiar deși am atras acestea destul de aproape
together-- 0x1, această este 0x2-- în realitate,
acest lucru acum ar putea fi adresa 0x10, de exemplu, si 0x11, 0x12 și,
și așa mai departe.
Și astfel, în cazul în care este cazul, ce se va ajunge aici în t?
>> Janelle: 0x10?
David J. MALAN: Exact.
Deci, 0x10.
Iar acum, întrebarea finală.
Ai, de departe, a trebuit să lucreze cel mai greu pentru un elefant până acum.
Până acum, dacă am trage în sus codul de din nou, atunci când o fac, în linie de trei,
dacă s egal este egal cu t, ceea ce sunt eu de fapt compararea pe care le-am atras aici?
>> Janelle: Cele două adrese?
David J. MALAN: Exact.
Deci, vreau să spun este e egal egal cu t?
Cu alte cuvinte, este de 1 egal egal cu 10?
Și, desigur, Răspunsul evident este acum, nu.
Și astfel acest program este în cele din urmă va imprima ceea ce, i-ai spune?
>> Janelle: Ar fi, ați tastat același lucru?
>> David J. MALAN: Deci, dacă s este 1 și t este de 10?
>> Janelle: Ai tastat lucruri diferite.
>> David J. MALAN: Exact.
Ai scris lucruri diferite.
În regulă.
Deci, o rundă de aplauze, dacă am putea, aici.
[Aplauze]
A fost dureros.
Știu.
Bine lucrat.
Deci, acum să vedem dacă nu putem tachineze pe langa ceea ce a fost fix.
Și, desigur, atunci când ne-am fixat asta-- pe care voi reprezenta acum în green--
am făcut o pereche de îmbunătățiri aici.
În primul rând, la fel cum un bun-simț verifica, eu sunt primul verificare
dacă e egal cu zero și t este egal cu zero.
Și ca să fie clar, când s-ar putea s sau t fi nul în cod ca asta?
Când s-ar putea s sau t fi nul.
Da?
>> Audiența: [inaudibil].
>> David J. MALAN: Exact.
În cazul în care șirul pe care utilizatorul tastat în este mult prea lung
pentru a se potrivi în memorie, sau unele caz colț ciudat de genul asta,
getString, așa cum vom vedea, la propriu astăzi, în documentația sa,
spune că va reveni nul ca o valoare deosebită santinelă,
sau doar un fel de simbol special înseamnă că ceva nu a mers bine.
Așa că vrem să verificați pentru că, pentru că se pare că
care nul este o valoare foarte periculos.
>> De multe ori, daca incerci sa faci ceva cu null implică o function-- trecerea
ca intrare, pentru instance-- că funcția s-ar putea foarte va prăbuși și, cu ea,
să ia în jos tot programul.
Deci, această a treia linie acum este doar un bun-simț verifica, verificarea erorilor, dacă vreți.
Asta e un obicei bun acum pentru ne pentru a obține în orice moment noi
încercați să utilizați o valoare care ar putea, eventual, să fie nul.
>> Acum, în al patrulea rând aici, "În cazul în care strcmp (s, t)," bine,
ce-i asta referindu-se la?
Ei bine, am spus acest lucru a fost un foarte succint numit funcție de comparație șir.
Și scopul său în viață este de a compara primul argument împotriva ei de-al doilea,
dar nu în ceea ce privește adresele lor, așa cum am făcut-o în mod neintenționat un moment
în urmă cu codul roșu, dar mai degrabă pentru a compara cele două
siruri de caractere din punct de vedere uman intuitiv mod prin compararea acest, împotriva acestei,
împotriva acestei, împotriva acestei, și apoi oprire în cazul în care și atunci când unul
sau ambele degete lovește un backslash 0.
Strcmp Deci, de ani în urmă cineva a implementat să pună în aplicare pentru noi funcționalitatea
pe care am sperat ne-ar fi ajuns de doar compararea a două valori simple.
>> Acum sincer, eu ține desen toate aceste numere diferite.
Dar realitatea este, am fost face astea tot timpul.
Și așa lasă-mă să merg mai departe și scrijelesc pe acestea
pentru a face un punct care, la sfârșitul de zi și merge mai departe,
Nu suntem de gând să-i pese ce abordează lucrurile sunt de fapt
în memorie.
Deci, eu nu am de gând să atragă aceste tipuri de numere prea mult acum,
Sunt doar un rezumat această distanță o ceva mai prietenos cu doar săgeți.
>> Cu alte cuvinte, în cazul în care s este un pointer, bine, hai să-l trage, literalmente,
ca un pointer, o săgeată orientată de la sine la altceva,
și nu vă faceți griji prea mult despre punctelor caracteristice acestor adrese
care, din nou, am făcut oricum.
Dar vom vedea acele adrese, uneori, atunci când depanare cod.
>> Acum între timp, acest program aici remedieri, desigur,
că problema prin compararea cele două șiruri.
Dar am dat peste o altă problemă.
Acest lucru a fost din copia programa ultimul timp,
prin care, am fost încercarea de a capitaliza doar primul caracter dintr-un șir.
Dar ceea ce a fost simptomul am văzut ultima dată când
un utilizator introduce o valoare, cum ar fi Gabe cu litere mici, pentru s,
apoi ne-am atribuit lui în t, ca și în al treilea rând acolo,
și apoi am încercat să valorifica t suport 0?
Care a fost efectul schimbarea t suport 0 aici?
>> Audiența: A schimbat uri.
>> David J. MALAN: Da, Am schimbat s, de asemenea.
Pentru că ceea ce se intampla de fapt?
Ei bine, lasă-mă să văd dacă pot curăța această imagine, după cum urmează.
>> În cazul în care s este, din nou, cuvântul g, a, b, e, backslash, 0, și s
vom continua desen ca o cutie aici, dar nu mai multe adrese.
Să nu mai face lucrurile.
Să desena o imagine pentru a simplifica lumea.
>> Când m-am t declara cu șir t, care creează că bucata de memorie.
Piața se întâmplă să fie 32 biți în cele mai multe calculatoare.
De fapt, dacă ați auzit vreodată de o calculator având o arhitectură pe 32 de biți,
într-adevăr fantezie-vorbesc, că doar înseamnă că folosește adrese de 32 de biți.
Și, ca o tehnică deoparte, dacă v-ați întrebat vreodată
de ce computere mai vechi, dacă tu de fapt a încercat să-i supa cu o mulțime de RAM,
ar putea avea doar un maxim de patru gigabytes de memorie RAM,
bine asta pentru ca, literalmente, computerul vechi ar putea doar
conta la fel de mare ca 4 miliarde, 4 miliarde de bytes,
pentru că a fost folosind 32 de biți Numerele de adrese.
>> Dar, în orice caz, în această exemplu, povestea e mult mai simplu.
t este doar un alt indicator, sau într-adevăr o stea char, aka șir.
Și cum nu vreau să actualizeze această imagine acum cu faptul că a doua linie de cod,
după punct, dot, dot?
Când m-am face string t este egal s punct și virgulă, cum se schimbă această imagine?
Da?
>> Audiența: [inaudibil].
>> David J. MALAN: Da.
Exact.
Tocmai am pus o săgeată din t box la aceeași adresă,
În același prima literă a adus.
Sau punct de vedere tehnic, în cazul în care acest lucru tip au fost încă de la 0x1,
E ca și cum am avut 0x1 aici și 0x1 aici.
Dar, din nou, cui îi pasă despre adresele?
E doar ideea care conteaza acum.
Deci, asta este ceea ce se întâmplă aici.
Deci, desigur, dacă faci t suport 0, care este notația matrice,
bineinteles-- și sincer, se pare ca exista o serie de peste aici,
dar acum există acest lucru ciudat.
Să știți că limbajul de programare, C, vă oferă această caracteristică,
prin care, chiar dacă t este un pointer, sau s este un pointer,
puteți utiliza în continuare că familiar, suport confortabil pătrat
notație pentru a merge la primul element, sau al doilea element, sau orice element
că indicatorul este îndreptat pentru că, probabil, ea
este, ca și în acest caz, arătând spre o anumită matrice.
>> Deci, cum putem rezolva această problemă?
Sincer, acest lucru este în cazul în care aceasta are o puțin copleșitor la prima vedere.
Dar aici este o versiune nouă și îmbunătățită.
>> Deci, prima, Primesc scăpa de bibliotecă CS50,
doar pentru a expune că S este într-adevăr o stea char, doar un sinonim.
Și T este, de asemenea, o stea char.
Dar ce se întâmplă cu privire la partea dreaptă a liniei
unde t este alocată o valoare?
>> Ce este malloc?
Ce este strlen?
Ce este sizeof (char)?
De ce naiba face acest lucru linie privire atât de complex?
Ce o face la un nivel înalt?
Ce se depozita în t?
Da?
Audiența: E alocarea unui anumită cantitate de spațiu de memorie.
Este pentru a stoca, cred, scrisori [neauzit].
>> David J. MALAN: Perfect.
Perfect.
Este alocarea unui anumit cantitatea de spațiu de memorie
pentru a stoca, probabil, scrisori viitoare.
Și, în special, malloc Prin urmare, se întoarce ce?
>> Audiența: Returnarea [neauzit]?
David J. MALAN: Exact.
Revenind adresa de memorie care, care este un mod fantezist de a spune,
returneaza adresa primul octet din memoria.
Este sarcina pe mine să-mi amintesc câtă memorie am de fapt
alocate sau a cerut malloc pentru.
>> Acum, cât de mult este asta?
Ei bine, chiar dacă nu există o mulțime de paranteze aici,
malloc are doar un singur argument.
Și eu precizând strlen de s, asa ca acorda mine, ca de multe bytes cum există în s,
dar să adăugați unul.
De ce?
Da?
>> Audiența: backslash 0.
David J. MALAN: Exact.
Avem de a face un pic de menaj.
Deci, pentru că există o bară oblică inversă 0, ne-ar aminti mai bine.
În caz contrar, ne vom pentru a crea un șir de caractere care
nu are ca terminator special.
>> Între timp, doar pentru a fi super- anal, am sizeof (char) au,
doar în cazul în care cineva se execută meu Codul nu pe aparatul CS50,
dar poate un alt computer în total în cazul în care caractere
sunt un octet, prin convenție, dar două bytes, sau ceva mai mult decât atât.
Este doar pentru a fi super, super-potrivnic la erori.
Chiar dacă, în realitate, este cel mai probabil, va fi un 1.
>> Acum, între timp, am merge mai departe și copia șir, t suport i este egal cu t suport uri.
Și voi amâna pentru săptămâna trecută codul sursă pentru a vedea ce se întâmplă.
Dar Takeaway cheie, și motiv pentru care am pus codul de acum în verde,
este pentru că ultima linie, t suport 0 este egal cu toupper,
are ca efect valorificare care șir?
t și / sau s?
Aceasta ultima linie de cod.
>> Doar t, pentru că ceea ce-i sa întâmplat de data aceasta,
dacă am anula ușor că ultimul pas, ceea ce sa întâmplat este, când eu numesc malloc,
Am obține, în esență, o bucată de memorie care este de aceeași mărime ca și originalul,
pentru că aritmetica am făcut-o.
Am stocarea în t adresa de care bucată de memorie.
Chiar dacă acest lucru pare frumos și destul de, frumos și gol,
realitatea este acolo, ceea ce vom ține de asteptare, valorile de gunoi aici.
Asta bucată de memorie s-ar putea foarte bine au fost folosite înainte,
câteva secunde, în urmă cu câteva minute.
Deci, ar putea exista absolut numere sau scrisori de acolo, doar prin accident.
Dar nu sunt valabile, până când am eu popula această bucată de memorie
cu caractere reale, așa cum am face în această buclă de acolo.
În regulă?
>> Deci, acum, punctul culminant al aceste trei exemple
care au fost aparent rupt ultima dată, acest exemplu Swap, această funcție
a lucrat în sensul că el a schimbat un și b.
Dar nu a mers în ce alt sens?
Da?
>> Audiența: [inaudibil].
>> David J. MALAN: Exact.
Dacă ar fi să numesc această funcție de la another-- de exemplu,
dintr-o asemenea funcție principală, unde Am o variabilă, x și y, așa cum am
a făcut săptămâna trecută, același cod, și trec în x și y
Pentru a schimba, și apoi apel Swap-- aceasta, desigur, este versiunea corectă
este ceea ce suntem pe cale să see-- nu a mers.
Deci, ce este fix?
>> Ei bine, astfel încât să fie clar, lasă-mă să merg mai departe
si-- dă-mi o secundă aici, și vezi dacă pot să-ți arăt ultima, care
va fi in-- să vedem dacă pot găsi acest adevărat OK fast--, [neauzit].
OK, asta este.
Deci, ignora comenzile Eu doar dactilografiere.
Vreau sa-l pentru a prelua de la în ultimul moment, de exemplu,
din ultimul timp, care este numit acum nu Swap.
>> Deci, nu Swap este în cazul în care ne-am oprit ultima dată,
prin care, am initializat x și y la 1 la 2.
Atunci eu numesc Swap, care trece în 1 și 2.
Și apoi această funcție a lucrat într-un fel,
dar ea nu a avut nici permanent efect de x și y.
Deci, intrebarea la îndemână este, cum acum Nu ne-am rezolva de fapt problema?
Care este soluția la îndemână?
>> Ei bine, în swap.c, care este nou astăzi, observa o pereche de diferențe.
x și y sunt aceleași.
Dar ceea ce este în mod clar diferit de linia 25?
Ce este nou acolo, dacă vă aduceți aminte cum arata acum un al doilea?
>> Audiența: [inaudibil].
>> David J. MALAN: Da.
Deci ampersand sunt o nouă piesă de sintaxă nu numai în acest program,
dar, de asemenea, în general, în CS50.
Până în prezent, nu cred că am vazut exemple
sau într-adevăr a vorbit despre ele în orice detaliu, altele decât, poate, preventiv
în secțiune, un ampersand ca asta.
Ei bine, se pare că ampersand este una din ultimele piese ale noului sintaxă
vom afla.
Tot ceea ce înseamnă adresa unor variabile.
La ce adresă are x trăi?
Dar ce adresă are y trăi?
Pentru că, dacă problemă fundamentală înainte
a fost că x și y au fost trecute ca de exemplare, ceea ce vrem cu adevărat să facem
se asigura Swap cu ca o comoară harta care duce la unde x și y de fapt
sunt în RAM, astfel încât Swap pot urmări că harta
și du-te la oriunde x sau y marchează locul și de a schimba valorile reale 1 și 2
acolo.
>> Deci Swap trebuie să se schimbe ușor prea.
Și la prima vedere, aceasta ar putea se pare un pic similar cu stele char.
Și într-adevăr este.
Deci, o este un pointer la ce tip de date, bazat pe această porțiune evidențiat?
Deci, este un întreg.
>> Deci, un nu mai este o int, este adresa de int.
Și în mod similar, b este acum de gând să fie adresa de int.
Așa că atunci când eu numesc acum Swap de la Main, Eu nu am de gând să dea Swap 1 și 2.
Am de gând să-l dea ca Ox-ceva și Ox-ceva,
două adrese care vor conduce Swap de locuri reale
în memoria calculatorului meu.
>> Deci, acum, punerea în aplicare a mea rămas trebuie să se schimbe un pic.
Ce este, evident, diferit acum în aceste trei linii de cod?
Exista aceste blestemate stele toate peste tot, bine?
Deci, ce se întâmplă aici?
Da?
>> Audiența: Este evident [neauzit].
>> David J. MALAN: Exact.
Deci, în acest context-- și acest lucru nu a fost cea mai bună decizie de design, desigur,
ani în urmă.
In acest context, în cazul în care trebuie doar o stea,
și nu aveți un tip de date, cum ar fi int, imediat la stânga,
în schimb va avea un semn de egalitate, în mod clar, în acest context, atunci când spui stea o,
înseamnă că merge la Adresa de e într-o.
Urmați harta comorii, ca să spunem așa.
>> Și între timp, în linia 37, aceasta înseamnă același lucru.
Du-te la adresa A, și a pus acolo ce?
Oricare ar fi la localizare care b specifică.
Cu alte cuvinte, du-te la b.
Ia valoare.
Du-te la o și, pe egalul semna, operatorul de atribuire,
pune că valoare acolo.
>> În mod similar, int temp este doar un int.
Nimic nu trebuie să se schimbe cu privire la temp.
E doar un pahar de rezervă de la Annenberg pentru lapte sau suc de portocale.
Dar trebuie să spun, du-te la b.
Du-te la asta destinație și pune în valoare temp acolo.
Deci, ce se întâmplă atunci?
Când de fapt, eu numesc Swap acest moment, în cazul în care acest prim tavă reprezintă aici Main,
acest al doilea tavă reprezintă Swap, atunci când Trec ampersand x și y ampersand
de la Main pentru a schimba, doar pentru a fi clar, ceea ce este această stivă cadru de recepție?
Da?
>> Audiența: [inaudibil].
David J. MALAN: Exact.
Adresa de x și y adresa.
Și vă puteți gândi la aceste cum ar fi adresele poștale.
33 Oxford Street și 35 Oxford Street, și tu
doriți să mutați cele două clădiri care sunt în acele zone.
>> Este un fel de idee ridicolă, dar asta e tot ce vrem să spunem prin adresa.
În cazul în care în lume se poate veți găsi aceste două int?
În cazul în care în lume nu poate tine găsi aceste două clădiri?
Deci, dacă în cele din urmă, după tot acest timp am du-te în codul sursă de astăzi și compila
Swap și a alerga ./swap, în cele din urmă, pentru Prima dată nu am vedea de fapt că
valorile mele au într-adevăr fost schimbate cu succes.
Și acum, putem lua chiar notă de acest lucru în, să zicem, gdb.
>> Așa că lasă-mă să merg în același fișier.
Lasă-mă să mergeți mai departe și a alerga gdb de ./swap.
Și acum, în Swap, am de gând să merg înainte și a stabilit un punct de pauză în Main.
Și acum am de gând să merg înainte și rulați programul.
Și acum vom vedea codul meu se opri la acea linie.
>> Dacă aș merge mai departe și de imprimare x, ceea ce ar trebui să văd aici?
Este o întrebare.
Spune din nou?
>> Audiența: [inaudibil].
>> David J. MALAN: Deci, numere aleatoare, poate.
Poate am noroc, și este frumos și simplu, cum ar fi 0.
Dar poate că e un număr aleator.
În acest caz, am avut noroc.
Se întâmplă să fie 0.
Dar este într-adevăr noroc, pentru că nu până când am
tipul următor și apoi de imprimare x are ca linie de cod, linia 19, a fost executat.
>> Între timp, dacă am introduce următorul nou, și acum imprima y, am de gând să văd 2.
Acum, dacă am introduce următorul, se va a obține un pic confuz, pentru că acum,
printf este de gând să apară pe pe ecran, așa cum a făcut-o. x este 1.
>> Să facem acest lucru din nou.
Și acum, iată unde lucrurile devin interesante.
Înainte de a apela Swap sau chiar pas în ea, să ia un pic cu ochiul.
x este, din nou, 1.
Y este, desigur, sanatatea rapidă verifica, 2, deci nu e greu acolo.
Dar ceea ce este ampersand x?
Răspuns, e un fel de funky caută.
Dar steaua int în paranteze este doar PIB-ul este un fel de a spune acest lucru este o adresă.
Nu e un int, este un pointer la un Int, sau altfel cunoscut ca o adresă.
>> Ce este acest lucru nebun?
Nu am mai văzut ceva chiar așa înainte.
Deci, aceasta este adresa la computerul meu memorie de unde x se întâmplă să trăiască.
Este Ox-ceva.
Și aceasta este, sincer, de ce Am inceput sa desenez săgeți,
în loc de numere, pentru că cine îi pasă cu adevărat
care int-ul este la un anumit Adresa de e atât de mare.
Dar bffff0c4, toate acestea sunt într-adevăr cifre hexazecimale,
care sunt de la 0 la f.
>> Deci, noi nu vom insista prea lung pe care aceste lucruri sunt.
Dar dacă imprima y, desigur, eu văd 2.
Dar ampersand y, eu văd această adresă.
Și preaviz, pentru curioși, cat de departe sunt x și y?
Puteți ignora cea mai mare parte a adresei.
Patru bytes.
Și asta e în concordanță cu nostru mai devreme susțin că cât de mare este un int?
Patru bytes.
Deci, se pare ca garnitură totul e în sus frumos, cum s-ar putea spera, în memorie.
>> Deci, acum, hai să fast forward la sfârșitul acestui poveste.
Să mergem mai departe și de tip pas, pentru a se arunca cu capul în funcția de Swap.
Acum observați, în cazul în care introduc o, e identic cu adresa de x.
Dacă aș tip b, e identic la adresa de y.
Deci, ce ar trebui să văd dacă am spun, du-te la adresa unui?
Deci, imprima stea o.
Deci stea înseamnă du-te acolo, în acest context.
Ampersand înseamnă ceea ce este adresa de.
Deci stea un mijloc 1.
Și stea imprimare b mi-a dat 2.
>> Și lasă-mă să-și asume, pentru moment, că cel puțin codul care
continuă să execute acum poate fi motivată prin faptul că în mod.
Dar ne vom revedea această idee înainte de mult timp.
Deci, această versiune a Swap este acum corect și permite
ne pentru a schimba acest tip de date special.
>> Deci orice întrebări atunci pe Swap?
Pe stele?
Pe adresa de?
Și veți vedea, cu problemă set 4, un fel de,
dar problema stabilit 5, cu siguranta, modul în care acestea lucrurile sunt utile și de a lua mult mai mult
confortabil cu ei, ca rezultat.
Orice?
În regulă.
Deci malloc este, din nou, această funcție care alocă doar memorie, memoria
alocare.
Și de ce este aceasta utilă?
Ei bine, în tot acest timp, ați fost utilizați malloc.
Dacă considerați că acum cum lucrări getString, probabil, e
a întrebat cineva pentru o bucată de memorie, oricând utilizatorul tastează un șir
în, pentru că noi cu siguranță nu stiu, ca personal CS50,
cât de mare aceste siruri de caractere pe care oamenii sunt de gând să tastați ar putea fi.
>> Deci, haideți să, pentru prima dată, începe să Desprindeți modul în care funcționează biblioteca CS50,
printr-o serie de exemple care ne va duce acolo.
Deci, dacă am deschide gedit și deschide scanf 0,
vom vedea codul de mai jos.
Scanf 0, disponibile pe site-ul de astăzi, are relativ puține linii de cod
aici, prin 14 20.
Și să vedem ce face.
Se declară un int, numit x.
Se spune ceva de genul, număr vă rog.
Și acum se spune, scanf% i, & x.
Deci, există o grămadă de lucruri noi acolo.
>> Dar scanf, vă puteți gândi un fel de a ca opusul printf.
printf, desigur, printuri pe ecran.
fel scanf de scanări de utilizator tastatură ceva el sau ea a scris.
>> % I este la fel ca printf.
Acest lucru înseamnă aștepta utilizator de tip int.
Și acum, de ce crezi că am s-ar putea trece scanf & x?
În cazul în care scopul în viață de scanf este de a obtine ceva de la utilizator,
ceea ce este sensul de trecându-l, și x, acum?
Da?
>> Audiența: [inaudibil].
David J. MALAN: Exact.
Oricare ar fi eu, omul, tastați, intrare meu va fi salvat în acea locație.
Nu este suficient, amintesc, la doar trece în x, pentru că am văzut deja,
de fiecare dată când trece doar o variabilă crud, ca un întreg, pentru o altă funcție,
sigur, se poate schimba asta variabilă, dar nu permanent.
Ea nu poate avea un efect asupra Main.
Se poate schimba doar propria copie locală.
Dar dacă, în schimb, tu nu faci da-mi int real,
dar mi-ai da indicatii care int, eu acum, fiind scanf,
sigur, eu pot urmări că aborda și a pus un număr de acolo
astfel încât să aibă acces la ea, de asemenea.
>> Așa că atunci când am rulat acest program, să vedem.
Asigurați-scanf 0 puncte slash, scanf 0.
Și dacă eu scriu acum un număr cum ar fi 50, multumesc pentru 50.
Dacă am introduce acum un număr ca negativ 1, pentru negativ 1.
Tastez acum un număr ca 1,5, hm.
De ce mi-a ignorat programul meu?
Ei bine, pentru că pur și simplu, i-am spus aceasta să se aștepte doar un int.
În regulă.
Deci asta este o versiune a acestui.
Să luăm lucrurile la un alt nivel și propune ca acest lucru nu este bun.
Și aici se află un exemplu foarte simplu de modul în care putem începe scrierea de cod
că alte persoane pot exploata sau compromite prin a face lucruri rele.
Deci linia 16, atât de asemănătoare în spirit de înainte,
dar eu nu sunt declarând că aceasta int acest moment.
Declar o stea char, aka șir.
>> Dar ce înseamnă de fapt acest lucru?
Deci, dacă eu nu specifica un address-- și Ii voi spune în mod arbitrar, tampon,
dar am putea numi aceasta e, de a fi simple-- și apoi să fac acest lucru, să-mi explice,
dacă ai putea, pe baza precedent logică, ceea ce este scanf face în linia 18,
dacă treci% s și tampon, care este o adresă?
Ce este scanf, dacă se aplică aceeași logică exact ca versiunea 0,
O să încercăm să facem aici, atunci când ceva tipuri de utilizatori în?
Da?
>> Audiența: [inaudibil].
>> David J. MALAN: Exact.
Scanf, de logica mai devreme, este de gând să ia șirul
că tastat uman in-- este acum un șir de caractere,
nu este un număr, probabil, în cazul în care el sau ea cooperates--
și că va încerca să pună că șir în memorie la orice adresă
tampon specifică.
Și acest lucru este mare, deoarece tampon este într-adevăr menit să fie o adresă.
>> Dar eu susțin acest program este buggy într-un mod foarte serios, pentru că ceea ce este de valoare
tampon în mod implicit?
Ce am inițializat în?
Ce bucată de memorie?
Eu nu am, nu?
>> Deci, chiar dacă am alocat o stele char că nu se mai numeste s,
se în schimb numit, buffer-- așa hai trage numele variabilei
acum ca buffer-- dacă nu am numit getString sau malloc aici,
ceea ce înseamnă că în mod eficient tampon este doar o valoare gunoi.
>> Acum, ce înseamnă asta?
Aceasta înseamnă că le-am spus scanf să se aștepte un șir de utilizator.
Și știi ce?
Indiferent de acest lucru se indică sa-- și trag semn de întrebare,
dar în realitate, ea va fi ca OX1, 2, 3, ceva corect?
Este o valoare fals că doar se întâmplă să fie acolo de la înainte.
Deci, cu alte cuvinte, este ca și cum tampon este doar
arătând spre ceva în memorie.
Nu am nici o idee ce.
>> Deci, dacă am introduce în Gabe acum, va pentru a încerca să pună g-a-b-e / 0 acolo.
Dar cine știe ce e asta?
Și în trecut, orice timp am încercat să atingă
memorie care nu face parte pentru noi, ceea ce sa întâmplat?
Sau aproape de fiecare dată.
Eroare de segmentare, nu?
>> Această săgeată, nu am nici o idee unde este indicare. e doar o valoare aleatorie.
Și, desigur, dacă ai interpreta o valoare aleatoare ca o adresă,
ai de gând să meargă la unele destinație aleator.
Deci, Gabe ar putea într-adevăr accident Programul meu în acest caz aici.
>> Deci, ce putem face e aproape la fel de rău?
Luați în considerare acest al treilea și exemplu finală de scanf.
Această versiune este mai bine în ce sens?
Dacă sunteți confortabil cu problema precedentă, acest lucru este mai bine.
De ce?
>> Audiența: [inaudibil].
David J. MALAN: Bine.
Deci, acest caz de linia 16 este mai bine, în sensul
că suntem în mod explicit alocarea unele memorie.
Noi nu utilizați malloc, suntem folosind săptămâna 2
Abordarea de doar declararea unei matrice.
Și am spus înainte că un șir este doar o serie de caractere,
deci acest lucru este total legitim.
Dar este, desigur, ca voi nota, dimensiune fixă, 16.
>> Deci, acest program este complet în condiții de siguranță, în cazul în care am de tip
în șiruri de câte un caracter, două caractere siruri de caractere, 15 de șiruri de caractere.
Dar, de îndată ce încep să tastați 16, 17, 18, 1000 șiruri de caractere,
unde se că șir va ajunge?
O să ajung în parte aici.
Dar cine știe ce altceva este dincolo de limitele
din acest tablou special?
>> Este ca și cum am a declarat 16 cutii de aici.
Deci, mai degrabă decât scoate tot de 16, vom ne prefacem că am atras 16.
Dar dacă apoi încearcă să citească un șir asta e mult mai mult, cum ar fi 50 de caractere,
Am de gând să înceapă punerea a, b, c, d, x, y, z.
Și acest lucru este, probabil, alt segment de memorie
că, din nou, s-ar putea provoca programul meu sa se prabuseasca,
pentru că eu nu am cerut pentru nimic mai mult decât de 16 bytes.
>> Deci, cui îi pasă?
Ei bine, aici e biblioteca CS50.
Și de cele mai multe acest lucru este doar cum ar fi instrucțiuni sus.
Biblioteca CS50, în tot acest timp, a avut această linie în linie 52.
Am văzut typedef, sau veți vedea typedef
în PSET 4, care creează doar o sinonim prin stele char poate fi mai
pur și simplu menționate ca șir.
Deci, aceasta este una dintre câteva roți de formare
am folosit secret sub capota.
>> Între timp, aici e funcția, getchar.
Acum se pare, nu e nici un corp să-l.
Și de fapt, dacă am ține defilare, eu nu fac de fapt
vezi orice punere în aplicare acestor funcții.
Ca un control bun-simț, de ce este asta?
>> Audiența: [inaudibil].
David J. MALAN: Da.
Deci, aceasta este fișierul antet.
Și fișiere antet conține prototipuri, plus alte lucruri, se pare,
ca typedefs.
Dar, în CS50.c, care ne-am nu ți-a dat pur și simplu,
dar a fost în aparat CS50 toate de această dată, adânc în interiorul de dosare sale,
observă că există un întreg grămadă de funcții de aici.
>> De fapt, hai să derulați în jos.
Să ignore cele mai multe dintre ele, pentru acum.
Dar, defilați în jos pentru a getint și a vedea cum funcționează getint.
Deci, aici este getint.
Și dacă vreodată te interesează cu adevărat cum te Int funcționează, aici este documentația acestuia.
Și printre lucrurile se spune este ce spune
ce gama de valori se poate returna.
Este, în esență negativ de 2 miliarde la pozitiv 2 miliarde, da sau de a lua.
>> Și se pare că, tot acest timp, chiar dacă nu ne-am
te-a verifica pentru el, în cazul în care ceva nu merge bine,
se pare că toate acest timp, are getint
a fost întoarcerea un special constant, nu null,
ci int_max, care este convenție doar un programator.
Aceasta înseamnă aici este o valoare deosebită.
Asigurați-vă că pentru a verifica acest lucru, doar în cazul în care ceva nu merge bine.
Dar noi n-am deranjat cu care până în prezent,
deoarece din nou, acest lucru trebui să fie benefic.
>> Dar cum getint fi puse în aplicare?
Ei bine, unul, este nevoie de nici un argument.
Știm că.
Aceasta returneaza un int.
Știm că.
Deci, cum functioneaza sub capota?
>> Deci, există aparent un infinit buclă, cel puțin aparența de unul.
Observați că suntem folosind getString.
Deci, asta e interesant. getint invită propria noastră funcție, getString.
Și acum, ce ar putea fi acest caz?
De ce am fi defensiv aici, în linie 165?
Ce-ar putea întâmpla în linie 164, doar pentru a fi clar?
Este același răspuns ca și înainte.
S-ar putea să fie doar din memorie.
Ceva nu merge bine cu getString, Trebuie să fie în măsură să se ocupe de asta.
Și motivul pentru care nu se mai întorc nul este că, tehnic, null este un pointer.
getint trebuie să se întoarcă un int.
Așa că am arbitrar a decis, în esență,
că 2 miliarde, da sau de a lua, se va să fie o valoare deosebită pe care n-am putea
obține de fapt, de la utilizator.
E doar valoarea o am de gând a deșeurilor pentru a reprezenta un cod de eroare.
>> Deci, acum, lucrurile devin un pic de fantezie.
Și nu e chiar aceeași funcție ca și mai înainte, dar este foarte asemănător.
Deci observa, declar aici, în linie 172, atât o int n și un char c.
Și apoi am folosi această linie de funky, sscanf, care se dovedește
nu scanează un șir de la tastatură.
Se ridică un șir existent care utilizatorul a tastat deja în.
Așa că am sunat deja getString, care înseamnă că am un șir în memorie.
sscanf este ceea ce ai apela o funcție de parsare.
Se uită la șirul am tastat în, caracter cu caracter,
și face ceva util.
Asta șir este stocat în linie.
Și știu că doar prin a merge copii de siguranță aici și spune, oh, bine,
L-am sunat, nu e de data asta, dar linie.
>> Iar acum acest lucru este un pic diferit.
Dar aceasta înseamnă în mod eficient, din motive vom val oarecum mâinile noastre la ziua de azi,
că suntem de verificare a vedea dacă utilizatorul tastat în
și int și, poate, un alt personaj.
În cazul în care utilizatorul a introdus într-un int, e O să fie stocate în n, pentru că eu sunt
trece acest lucru prin adresa, nou truc care le-am văzut azi.
În cazul în care utilizatorul, de asemenea, tastat în așa 123x, că x
se va ajunge o scrisoare în caracter c.
>> Acum, se pare că sscanf mi se va spune, inteligent,
cât de multe variabile fost sscanf posibilitatea de succes pentru a umple.
Deci, prin această logică, în cazul în care funcția de Sunt de punere în aplicare este getint,
dar eu sunt de verificare, potențial, pentru utilizator
pentru a fi introdus într-un int urmată de altceva,
ce vreau de sscanf valoare reveni cu adevărat să fie?
În cazul în care scopul este de a obtine doar un int de utilizator?
>> Deci, dacă sscanf se întoarce 2, ce înseamnă asta?
Utilizatorul tastat ceva de genul, pur și simplu,
123x, care este doar un nonsens.
Este o stare de eroare, și Vreau să verific pentru că.
>> Deci, dacă tipurile de utilizatori în acest, prin această logică, ceea ce face sscanf reveni,
ai spune?
Deci, o să se întoarcă 2, pentru că 123 este de gând să meargă în aici,
și x se va ajunge aici.
Dar eu nu vreau x sa se umple.
Vreau să sscanf pentru a reuși numai în completarea prima de variabilele sale.
Și de aceea am doresc sscanf să se întoarcă 1.
>> Și dacă acest lucru este un pic peste cap pentru moment, asta e cu totul bine.
Realizati deși, că unul dintre Valorile de getint și getString
este că vom face un heck de o mulțime de eroare de verificare de genul asta așa
că, până în prezent, puteți destul de mult tastați nimic la tastatură,
Si noi vom prinde.
Și cu siguranță, personal, nu va fi cu siguranta
fi sursa de o eroare în ta Programul, pentru că suntem în defensivă
verificarea pentru toate prost lucruri pe care un utilizator ar putea face,
cum ar fi tastarea un șir de caractere, atunci când ai vrut int.
Deci, pentru acum-- vom veni înapoi la acest lucru înainte de long--
dar în tot acest timp, getString și getint au
fost sub capota folosind această Ideea de bază a adreselor de memorie.
>> Deci, acum, hai să facem lucrurile o ceva mai user-friendly.
După cum vă amintiți, la ultima Binky timp-- dacă mouse-ul meu va cooperate-- astfel
am avut acest cod, care sincer, este destul de lipsit de sens.
Acest cod atinge nimic utilă, dar a fost un exemplu
că profesorul Parlante utilizat pentru a reprezenta
ceea ce se întâmplă într-o program care implică memorie.
>> Așa că haideți să povestesc această poveste foarte scurt.
Aceste prime două linii, în Engleză, nu ceea ce, i-ai spune?
Doar în mod rezonabil uman, dar ușor punct de vedere tehnic, să ia o lovitură de cuțit.
Audiența: [inaudibil].
>> David J. MALAN: OK, te stabilirea adrese pentru x și y variabile.
Nu chiar, pentru că x și y nu sunt variabile în sensul tradițional.
x și y sunt adrese sau va stoca adresa.
Așa că haideți să încercăm încă o dată.
Nu este un început rău, totuși.
Da?
>> Audiența: [inaudibil].
David J. MALAN: Bine.
Cred că e un pic mai curat.
Declararea doi indicatori, două numere întregi.
Și noi îi cheamă x și y.
Sau, dacă ar fi să atragă aceasta ca o imagine, din nou,
amintesc pur și simplu că toate facem cu prima linie
este de a atrage o cutie ca aceasta, cu o anumită valoare gunoi în ea,
și ea apel x, și apoi altă cutie ca aceasta,
cu o valoare gunoi în ea, sun y.
Ne-am declarat două indicii că în cele din urmă
va stoca adresa de int.
Deci, asta e tot acolo.
>> Deci, atunci când Binky a făcut acest lucru, lut am uitat ca aceasta.
Și Nick doar un fel de înfășurat săgețile,
ca și cum ei nu sunt nicăieri îndreptat în special, pentru că sunt doar
Valorile de gunoi.
Ei nu sunt inițializate explicit oriunde în particular.
>> Acum, următoarea linie de cod, amintesc, a fost aceasta.
Deci, în mod rezonabil, user-friendly, dar English oarecum tehnic,
ceea ce este această linie de cod faci?
Da?
>> Audiența: [inaudibil].
>> David J. MALAN: Perfect.
Este alocarea bucată de de memorie care este de dimensiunea unui int.
Și asta e pe jumătate răspunsul.
Ați răspuns dreapta jumătate a expresiei.
Ce se întâmplă pe din partea stanga a semnului egal?
Da?
Audiența: și atribuie l la variabila x?
>> David J. MALAN: și agenții acesta a variabilei x.
Deci, pentru a recapitulare, alocă din partea dreaptă suficientă memorie pentru a stoca un int.
Dar malloc special returneaza adresa
de care bucată de memorie, pe care le-ați doar propus este stocat în x.
>> Deci, ce Nick a făcut ultima dată cu Binky este el a târât că pointer afară, lutul,
pentru a indica acum la o bucată albă de memorie care este egală cu dimensiunea de un int.
Și într-adevăr, că este menit pentru a reprezenta patru octeți.
>> Acum, următoarea linie de cod a făcut acest lucru, stea x devine 42.
Deci 42 este simplă, pe de partea dreaptă, sensul vieții.
Partea stângă, stele x înseamnă ce?
Că prea s-ar putea avea gone-- este OK.
OK.
>> Audiența: Practic, du-te la [neauzit]
David J. MALAN: Bine.
Audiența: [inaudibil].
David J. MALAN: Exact.
Din partea stanga, înseamnă a merge la x.
x este adresa.
E ca și cum 33 Oxford Street, sau OX1.
Și stea x înseamnă du-te la asta aborda și a pus acolo ce?
42.
>> Deci, într-adevăr, asta este exact ceea ce a făcut Nick.
A început cu de, în esență, mental
arătând cu degetul x, urmând săgeata
la caseta de alb pe-dreapta lateral, și punerea numărul 42 acolo.
Dar apoi lucrurile s-au puțin periculos, nu?
Lui Binky pe cale să piardă capul.
>> Steaua y este egal cu 13, ghinion, ce înseamnă?
Deci, mijloace y stele du-te la adresa din y.
Dar ceea ce este adresa la y?
Bine, e valoare gunoi, nu?
Am desenat ca un semn de întrebare.
Nick este atras ca o săgeată curbată în sus.
Și, de îndată ce va încerca să face y stele, spunând: du-te acolo,
dar nu există un legitim adresa, e un fals localizare,
Programul se va prăbuși.
Și capul Binky se întâmplă pentru a zbura de pe aici, așa cum a făcut-o.
>> Deci, în cele din urmă, acest program a fost doar defect din apartament.
A fost un program de buggy.
Și trebuie să fie stabilită.
Și singura cale, într-adevăr, să-l repari ar fi, de exemplu, această linie,
care nici macar nu ajunge la, deoarece Programul sa prăbușit prea repede.
Dar dacă ar fi să se stabilească acest lucru, ceea ce efect nu face y x egale avea?
Ei bine, se arată, în esență, y la indiferent de valoarea x este îndreptat la.
>> Deci, în povestea lui Nick, sau povestea Binky lui, atât
x și y au fost îndreptat la bucată albă de memorie,
astfel încât, în cele din urmă, atunci când Nu star Y este egal cu 13 din nou,
ajungi pune 13 în locul potrivit.
Deci, toate aceste linii sunt perfect legitim, cu excepția pentru aceasta,
când sa întâmplat înainte de a de fapt atribuit y o anumită valoare.
>> Acum, din fericire, tu nu faci Trebuie să raționeze prin toate
de aceste tipuri de probleme pe cont propriu.
Lasă-mă să mergeți mai departe și deschide o fereastră terminal aici
și deschide, pentru o clipă, un program de super-scurt, care
De asemenea, este un fel de lipsit de sens.
E urât.
Ea nu atinge nimic folositor.
Dar ea nu demonstrează probleme de memorie, așa că haideți să aruncăm o privire.
>> Principal, super-simplu.
Se pare că solicită o funcție, f, iar apoi revine la 0.
E cam greu să te pui asta.
Deci, principala este destul de bun, așa de departe.
>> Deci f este problematic.
Și nu a pus mult efort în numind-o
aici, pentru a menține accentul pe codul.
f are două linii.
Și să vedem ce se întâmplă acum pe.
Deci, pe de o parte, aici-- și lasă-mă să fac
această concordanță cu cel anterior exemplu-- pe de o parte,
partea stângă este a face ceea ce, în limba engleză?
Acesta e--
Audiența: Crearea unui pointer.
David J. MALAN: Crearea unui pointer la un int și numindu-l x.
Deci, se creează una din acele cutii Tot bazându-se pe ecranul tactil.
Și acum, pe-dreapta lateral, malloc, desigur,
este alocarea unui segment de memorie.
Și ca să fie clar, cum mult de memorie este aparent
alocarea, dacă doar un fel de a face matematica aici?
>> Deci, este de 40 bytes.
Și știu că doar pentru că știu că o Int, pe aparatul CS50, cel puțin,
este de patru bytes.
Deci, de 10 ori 4 este de 40.
Deci, aceasta este stocarea unui x, adresa din prima out de 40 de int care
s-au alocat spațiu înapoi, în spate, în spate, în spate.
>> Și asta e cheia despre malloc.
Nu e nevoie de un pic de memorie aici, un pic de aici, un pic de aici.
Acesta vă oferă o bucată de memorie, contiguu, din activități de exploatare
sistem.
>> Acum, ce zici de asta, x suport 10 este egal cu 0?
Linie arbitrar de cod.
Ea nu atinge nimic folositor.
Dar este interesant, deoarece x suport 10--?
Da?
>> Audiența: [inaudibil]?
>> David J. MALAN: x Suport 10 nu trebuie să fie nul.
Detaliul nul vine numai în joc cu siruri de caractere, la sfârșitul unui șir.
Dar un gand bun.
>> Cât de mare este această matrice, chiar deși am alocat 40 de bytes?
Este de la 0 la nouă, nu?
E 10 int, totală.
40 de bytes, dar 10 int, indexate de la 0 la 0.
>> Deci, ce este că x suport 10?
Este de fapt ceva Valoarea gunoi necunoscut.
Este de memorie care nu-mi aparține.
N-ar trebui atinge că byte număr 41, 42, 43, 44.
Mă duc puțin prea departe.
>> Și, într-adevăr, dacă am alerga aceasta program, acesta s-ar putea foarte bine accident.
Dar, uneori, vom avea noroc.
Și astfel doar pentru a demonstra asta-- și sincer,
nu știi niciodată înainte de a Nu it-- să ruleze acest lucru.
Nu a de fapt accident.
>> Dar dacă am schimba acest lucru, pentru exemplu, să fie ca 1000,
pentru a face acest lucru într-adevăr deliberat, să vedem
dacă putem să-l sa se prabuseasca de data asta.
OK, nu a accident.
Ce zici de 100.000?
Să-l refacă, iar acum se reface.
OK.
Pfiu.
În regulă.
Deci, se pare, din nou, acestea segmente de memorie, ca să spunem așa,
sunt destul de mari, astfel încât să putem ajunge din nou și din nou noroc.
Dar, în cele din urmă, odată ce te ridicol și într-adevăr merge departe pe ecran,
atingeți de memorie care într-adevăr, într-adevăr nu-ți aparține.
>> Dar sincer, acestea tipuri de bug-uri vor
pentru a fi mai greu și mai greu să dau seama pe cont propriu.
Dar, din fericire, ca programatori, ne-am instrumente care ne permit să facem acest lucru pentru noi.
Deci, aceasta este, probabil, unul de cele mai urate programelor,
chiar mai urât decât producția gdb lui.
Dar ea are întotdeauna o linie sau doi, care sunt foarte utile.
>> Valgrind este un program care ajută tu nu debug un program, în sine,
dar găsi legate de memorie probleme, în mod specific.
Aceasta se va desfășura în mod automat codul de te si uita-te pentru cel puțin două lucruri.
Unul, ai făcut ceva accidental ca memorie tactil
care nu vă aparține?
Acesta vă va ajuta să găsiți aceste cazuri.
>> Și doi, aceasta va ajuta veți găsi ceva numit
pierderi de memorie, pe care le avem complet ignorat, în mod naiv,
de ceva timp și fericire.
Dar se pare că, tot acest timp, ori de câte ori
te-am sunat getString în atât de multe dintre programele noastre,
ceri de operare sistem de memorie,
dar aveți orice amintire de tot ea da
înapoi, face NEALOCATE, sau liber, așa cum se numește.
Nu, pentru că nu ne-am ți-a cerut să facă acest lucru.
>> Dar în tot acest timp, programele de care le-ați scris în C
Au fost scurgeri de memorie, cere de operare
Sistem pentru tot mai mulți memorie pentru siruri de caractere și de fleacuri,
dar nu se preda înapoi.
Iar acum acest lucru este un pic de o simplificare excesivă,
dar dacă ai vreodată rula Mac-ul sau PC-ul de ceva timp, de deschidere
o mulțime de programe, programe poate de închidere,
și chiar dacă dumneavoastră calculator nu sa prăbușit,
se face atât de mult mai lent, ca și cum este într-adevăr
folosind o mulțime de memorie sau resurse, chiar dacă,
dacă tu nu ești nici măcar atingeți tastatura,
care ar putea fi--, dar nu a putut intotdeauna-- fie că programele pe care le rulați
au ele însele pierderi de memorie.
Și ei tot întreb sistemul de operare pentru mai mult și mai multă memorie, dar uitând de el,
de fapt, nu folosind-o, dar având, prin urmare, memorie departe
de la alte programe care s-ar putea dori.
Deci, asta este o explicație comună.
Acum, aici e unde e Valgrind ieșire este complet
atroce a celor mai puțin și mai confortabil la fel.
Dar interesant Chestia asta e chiar aici.
Ea îmi spune o scriere invalid de Dimensiunea patru se întâmplă în acest program,
în special, la linia 21 din memory.c.
>> Dacă mă duc la linia 21, hm, nu într-adevăr este o scriere invalid de dimensiune patru.
De ce dimensiune patru?
Ei bine, acest number-- și ea ar putea fi orice-- este un int.
Deci, este de patru octeți.
Asa ca imi pun patru bytes în cazul în care acestea nu fac parte.
Asta e ceea ce Valgrind este, de fapt mi-a spus.
Mai mult decât atât, el va, de asemenea, Spune-mi, cum vom vedea,
ca tu a alerga aceasta într-un viitor PSET, în cazul în care și când ai scurgeri de memorie, care într-adevăr
Eu am, pentru că am sunat malloc, dar eu nu am de fapt
numit, în acest caz, gratuit, care vom vedea în cele din urmă
este opusul malloc.
>> Așa că acum, cred, un ultim exemplu.
Deci, acesta este un pic mai mult arcane, dar este, probabil,
cel mai mare motiv de fi atent cu memorie,
și motivul pentru care multe programe și / sau servere de web, chiar la această zi,
sunt preluate de către baietii rai undeva pe internet, care sunt într-un fel
trimiterea de pachete false la server-ul dvs. încearcă să facă un compromis conturile tale,
sau de a lua datele, sau doar în general, preia o mașină.
Buffer overflow, ca Numele sugerează, mijloace
debordant nu o int, dar un tampon.
Și un tampon este doar un mod fantezist de a spune că este o grămadă de memorie.
>> Și într-adevăr, am sunat un șir înainte tampon, în loc de s.
Pentru că, dacă e un tampon, ca, în sensul YouTube,
sau de fiecare dată când te uiți la un film, este posibil să fi văzut tamponarea cuvânt,
dot, dot, dot.
Este incredibil de enervant.
Și asta înseamnă doar că player-ul video
este încercarea de a descărca o mulțime de bytes, o mulțime de bytes
de la un video de pe internet.
Dar e lent, așa că încearcă pentru a descărca o grămadă de ele
pentru a umple un tampon, un container, astfel încât aveți suficient de bytes care se poate apoi
vă arată video, fără a întrerupe în mod constant.
Dar se pare că, puteți au un tampon pentru atât de mare.
Dar încercați să puneți atât de mult de date în ea, și foarte lucruri rele se pot întâmpla.
Deci, de exemplu, să ne uităm la acest teaser finală de exemplu.
Acesta este un alt program că, la prima vedere,
nu face nimic foarte util.
Are o funcție principală care apelează această funcție, f.
Și această funcție, f, aici, are o matrice char, numit C, de dimensiune 12.
Și atunci se folosește acest Noua funcție numită strncpy.
>> Se pare că, cu acest simplu, simplu linie de cod, la doar două linii,
ne-am făcut întreg programul meu, și, prin urmare, întreaga mea calculator,
și contul meu de utilizator, și greu meu conduce potențial vulnerabile la nimeni
care știe și este destul de bun pentru a rula acest program cu o anumită linie de comandă
argument.
Cu alte cuvinte, în cazul în care acest tip de rău pune în interiorul argvargv [1] prin tastarea
la tastatura un foarte special pregatit șir, nu abc, 123, dar, în esență,
simboluri binare care reprezintă executabil cod, un program care el sau ea a scris,
cu acest program simplu, care este reprezentant de mii de programe
care sunt la fel de vulnerabile, îndrăznesc să spun, el sau ea poate șterge în cele din urmă toate
fișierele de pe hard-disk, pentru a primi un clipește rapid, astfel încât el sau ea poate
Tip comenzi pe cont propriu, e-mail toate fișierele de mine.
Ceva ce pot face, el sau ea poate face cu acest cod.
>> Noi nu prea va rezolva acest lucru încă.
Și, de fapt, se va implica o imagine puțin
ca aceasta, pe care vom veni în curând pentru a înțelege tot mai bine.
Dar pentru ziua de azi, să se încheie pe ceea ce este, sperăm, un pic mai
de înțeles gluma XKCD, până când vom relua data viitoare.
În regulă.
Ne vedem miercuri.
>> [MUSIC JOC]
>> Vorbitor: Și acum, adânc gânduri, de Daven Farnham.
Memoria este ca sari într-o grămadă de frunze de aur pe o duminica dupa-amiaza.
Vântul, se clatina ta hair-- oh, mi-e dor de zilele when--
>> [Râsete]