[MUSIC JOC]
>> DOUG LLOYD: OK asa ca o sugestie înainte de a începe aici.
Dacă nu ați vizionat video de pe indicative ar putea să doriți să faceți acest lucru în primul rând.
Deoarece acest film este un alt mod de lucru cu pointeri.
>> Deci o să vorbească despre unele concepte
că capacul în indicative video, iar noi suntem
O să treacă peste ele acum, presupunând că acestea sunt deja
un fel de înțeles.
Deci, asta e doar avertisment echitabil că, dacă vedeți acest videoclip
și nu au văzut indicii video, s-ar putea fel de
zbura peste cap un pic.
Și așa ar fi mai bine să-l urmăriți în această ordine.
>> Deci, am văzut deja unul mod de a lucra cu indicii,
care este declarăm o variabilă, iar apoi ne-am
declara o altă variabilă, un pointer variabilă, care indică spre el.
Deci am creat un variabilă cu un nume, am
a creat un al doilea variabilă cu un nume, și ne-am îndrepta a doua variabile
la acea primă.
Acest tip de are un problemă deși, pentru că
ne cere să știm exact câtă memorie suntem
avea nevoie în momentul programul nostru este compilat.
>> De ce este asta?
Pentru că trebuie să fie în măsură să numească sau identifice toate variabilele posibile
am putea întâlni.
Am putea avea o serie care ar putea fi în măsură să dețină o mulțime de informații,
dar nu este încă exact suficient de precise.
Ce se întâmplă dacă nu știm, Ce se întâmplă dacă nu avem nici o idee
cât de mult avem nevoie de la compilare?
Sau dacă programul nostru va candideze pentru un timp foarte lung,
acceptarea diverse utilizator date, și nu poate într-adevăr
estima dacă suntem avea nevoie de 1.000 de unitati?
>> Nu e ca și cum putem spun la linia de comandă
introduceți câte un produs credeți că veți avea nevoie de.
Ei bine, ce dacă cred este greșit?
Alocare de memorie dinamică un fel de ne permite modul
pentru a obține în jurul valorii de această problemă special.
Și modul în care o face este prin utilizarea indicii.
>> Putem folosi indicii la avea acces la dinamic
memorie alocată, memorie care este alocate după cum programul se execută.
Nu este alocat în timpul compilării.
Când aloca dinamic memorie vine de la un bazin
de memorie cunoscut sub numele de heap.
Anterior tot memoria ne-am fost de lucru cu în cursul
a fost provenind de la un bazin de memorie cunoscut ca stiva.
O modalitate buna de a în general păstra în mind-- și această regulă
nu deține întotdeauna adevărat, dar destul de mult aproape
deține întotdeauna true-- este că orice timp vă dau un nume de variabilă se
probabil trăiește pe stiva.
Și de fiecare dată când nu da o variabilă un nume,
pe care le puteți face cu memorie dinamică alocare, trăiește pe heap.
>> Acum am un fel de a prezenta acest lucru ca dacă există aceste două bazine de memorie.
Dar este posibil să fi văzut acest Diagrama, care este, în general,
o reprezentare a Ce memorie arata ca,
și nu o să aibă grijă de toate lucrurile din partea de sus și de jos.
Ceea ce ne interesează este aceasta parte din mijloc aici, heap și stiva.
După cum puteți vedea prin se uită la acest diagramă,
acestea de fapt, nu sunt două bazine separate de memorie.
Este una piscină comună de memorie în cazul în care începe, în acest vizuală
începe în partea de jos și începeți să umple
din partea de jos cu stiva, și încep de la partea de sus și începe completarea
de sus în jos cu grămada.
Dar într-adevăr este același bazin, e doar
locuri diferite, locatii diferite în memorie care sunt alocate.
Și puteți alerga afară de Memoria fie având
heap merge până la capăt la partea de jos, sau au
stiva merge tot drumul la partea de sus, sau având heap și stiva
întâlni împotriva celuilalt.
Toate acestea pot fi condiții care cauzeaza programul
la a alerga afară de memorie.
Astfel încât să păstreze în minte.
Când vorbim despre heap și stiva
suntem într-adevăr vorba despre aceeași bucată generală de memorie, doar
diferite porțiuni ale acestei memorie.
>> Deci, cum putem obține dinamic alocate de memorie în primul rând?
Cum programul nostru obține Memoria ca se execută?
Ei bine, C oferă o funcție numită malloc, alocator memorie, care
a efectua un apel la, și treceți în cât de multe bytes de memorie pe care doriți.
Deci, dacă programul se execută si doriti un număr întreg de execuție,
s-ar putea Mallock patru octeți memorie, malloc paranteze patru.
>> Mallock va trece prin Cautati prin grămada,
pentru că suntem în mod dinamic alocarea de memorie,
și se va întoarce la tine un pointer la care memoria.
Nu te da ca memory-- nu oferă un nume,
vă oferă un pointer la el.
Și astfel că de aceea i-am spus din nou că este important să poate
au vizionat video indicii înainte de a ajunge prea departe în asta.
Deci malloc va vă dau înapoi un pointer.
>> Dacă Mallock nu se poate da nici memorie pentru că v-ați alerga afară,
l voi da înapoi un pointer nul.
Îți amintești ce se întâmplă dacă am încercați și dereference un pointer nul?
Am suferi o defecțiune SEG, nu?
Asta nu e, probabil, bine.
>> Deci, de fiecare dată când face un apel pentru a vă malloc mereu, mereu
nevoie pentru a verifica dacă este sau nu pointer-a dat înapoi este nulă.
Dacă este, aveți nevoie pentru a termina programul pentru că dacă încerci și dereference
indicatorul nul mergi să sufere o eroare de segmentare
și programul este va prăbuși oricum.
Deci, cum putem static obține un număr întreg?
>> int x.
Am făcut, probabil, că o grămadă de ori, nu?
Acest lucru creează o variabilă numită x care trăiește pe stiva.
Cum putem obține un număr întreg dinamic?
Int px stele este egal cu malloc 4.
>> Sau mai corect am spune px stea Int
este egal cu dimensiunea malloc de Int, doar pentru a arunca unele mai
numere magice în jurul programului nostru.
Acest lucru se întâmplă pentru a obține pentru noi patru octeți de memorie din heap,
și indicatorul ne înapoi la este numit px.
Și apoi doar cum am făcut anterior am
poate dereference px la accesa că memoria.
Cum putem obține un număr întreg de la utilizator?
Putem spune int x este egal cu a obține Int.
Asta e destul de simplă.
Ce se întâmplă dacă dorim să creăm un tablou de x flotoare care trăiesc pe stiva?
float stack_array-- că e numele noastre array-- paranteze pătrate x.
Care va crea pentru noi o serie de x flotoare care trăiesc pe stiva.
Putem crea o serie de flotoare care trăiește pe heap, de asemenea.
Sintaxa ar putea arata o puțin mai mult greoaie,
dar putem spune float heap_array stele este egal
malloc x ori mai mare a flotorului.
Am nevoie de suficient spațiu pentru a ține Valorile punctul X plutitoare.
Deci spun că am nevoie de 100 pluteste, sau 1.000 de flotoare.
Deci, în acest caz, ar fi 400 octeți pentru 100 de flotoare,
sau 4.000 bytes pentru 1.000 de flotoare, deoarece fiecare flotor preia
patru octeți de spațiu.
>> După ce faci acest lucru pot folosi pătrat sintaxă suport pe heap_array.
Așa cum mi-ar pe stack_array, am pot accesa elementele sale individual
folosind heap_array zero, unu heap_array.
Dar amintesc motivul pentru care putem face asta se datorează faptului că numele unui tablou în C
este într-adevăr un pointer la Primul element care matrice lui.
Deci faptul că suntem o declararea matrice de flotoare pe stiva aici
este de fapt un pic înșelătoare.
Suntem într-adevăr se află în a doua linie de cod acolo
crearea, de asemenea, un pointer la o bucată de memorie care apoi facem ceva de lucru cu.
>> Aici e marea problemă cu alocate dinamic memorie, deși,
și de aceea este foarte important să se dezvolte unele obiceiuri bune
când lucrați cu ea.
Spre deosebire de declarat static memorie, memoria
nu este returnat automat la sistemul atunci când funcția se face.
Deci, dacă avem principal, și principal solicită o funcție
f, atunci când f finisaje orice ar face și returnează control al programului
Înapoi la, toată memoria care f folosit este dat înapoi.
Acesta poate fi utilizat din nou de un alt program,
sau o altă funcție care este chemat mai târziu în principal.
Se poate folosi aceeasi memorie din nou.
>> Dacă ați dinamic aloca memorie deși
trebuie să-i spuneți în mod explicit sistem care ai terminat cu ea.
Va ține pe ea pentru tine, care ar putea duce la o problemă de voi scurge
de memorie.
Și, de fapt, uneori, ne referim în acest sens printr-o scurgere de memorie.
Și, uneori, aceste pierderi de memorie poate fi de fapt foarte devastator
pentru performanța sistemului.
>> Dacă sunteți un utilizator de internet frecvent s-ar putea utiliza anumite browsere web,
și nu voi da nume aici, dar există unele browsere web acolo
că sunt cunoscute pentru a avea de fapt pierderi de memorie care nu te fixe.
Și dacă vă lăsați browser-ul deschis pentru o perioadă foarte lungă de timp, zile
și zile, sau săptămâni, vă uneori s-ar putea observa că sistemul dvs.
este de funcționare într-adevăr, într-adevăr lent.
Și motivul pentru care este faptul că browser-ul a alocat de memorie,
dar atunci nu a spus sistemul că se face cu ea.
Și astfel încât lasă mai puțină memorie disponibil pentru toate celelalte programe
de a avea de a împărtăși, pentru că ești leaking-- că browser-ul web
Programul se scurge de memorie.
Cum ne da inapoi de memorie când am terminat cu ea?
Ei bine, din fericire e un mod foarte ușor de a face acest lucru.
Noi doar l gratuit.
Există o funcție numită gratuit, acceptă un pointer la memorie,
și suntem bine să plec.
>> Deci, să spunem că suntem în mijloc de programul nostru,
vrem să malloc 50 de caractere.
Vrem să malloc o matrice care poate capabil să mențină 50 de caractere.
Și când ne un pointer înapoi la că, nume care indicatorul este cuvântul.
Facem tot ce suntem de gând să faci cu cuvânt,
și apoi atunci când suntem făcut noi doar gratuit.
Și acum ne-am întors pe cei 50 bytes de memorie înapoi în sistem.
Unele alte funcții pot să le utilizeze.
Noi nu trebuie să vă faceți griji cu privire la ce a suferit un scurgere de memorie pentru că am eliberat cuvânt.
Ne-am dat memoria spate, așa am terminat de lucru cu ea.
Deci, există trei reguli de aur care ar trebui
să fie păstrate în minte ori de câte ori ești alocarea dinamică de memorie
cu malloc.
Fiecare bloc de memorie care vă malloc să fie eliberat
înainte de a termina programul de funcționare.
Acum, din nou, în aparatul sau în IDE acest tip de loc pentru tine, oricum
atunci când acest lucru se va întâmpla Tu-- oricum atunci când programul se termină,
toate memoria va fi lansat.
Dar e de codificare, în general, bine practică întotdeauna, atunci când ați terminat,
elibera ceea ce ai mallocd.
>> Asta a spus, doar lucruri pe care ai mallocd ar trebui să fie eliberat.
Dacă ați declara static un întreg, int x semi-colon,
care trăiește pe stiva, tu Nu vreau să elibereze apoi X.
Deci numai lucruri pe care le-ați mallocd ar trebui să fie eliberat.
>> Și, în fine, nu face ceva gratuit de două ori.
Care pot duce la o altă situație ciudat.
Deci tot ce ai mallocd trebuie să fie eliberat.
Numai lucruri pe care le-ați malloc trebuie eliberat.
Și nu face ceva gratuit de două ori.
>> Așa că hai să printr-un exemplu aici de ceea ce unii alocate dinamic
memorie ar putea arata ca mixt în cu unele memorie statică.
Ce s-ar putea întâmpla aici?
Vezi dacă poți urmări de-a lungul și ghici ce-i
o să se întâmple așa cum vom merge prin toate aceste linii de cod.
>> Deci, noi spunem Int m.
Ce se întâmplă aici?
Ei bine, acest lucru este destul de simplă.
Am crea o variabila integer numit m.
Am culoare verde, pentru că asta e culoarea
pe care îl folosesc, atunci când vorbesc despre variabile intregi.
E o cutie.
Se numește m, și puteți magazin întregi interior.
>> Ce se întâmplă dacă spun, atunci int stea o?
Ei bine, asta e destul de similare.
Creez o cutie numit.
Este capabil să mențină Int stele, pointeri la întregi.
Așa că eu sunt o colorat verde-ish, de asemenea.
>> Știu că are ceva de a face cu un număr întreg,
dar nu se e un număr întreg.
Dar e destul de mult aceeași idee.
Am creat o cutie.
Ambele dreapta acum live pe stiva.
Le-am dat ambele nume.
>> stele int b este egal cu dimensiunea malloc de Int.
Acesta ar putea fi un pic cam complicat.
Ia-o a doua și cred despre ceea ce ar aștepta să se întâmple pe acest diagrama.
stele int b este egal cu dimensiunea malloc de Int.
>> Ei bine, acest lucru nu creează doar o cutie.
Acest lucru creează de fapt două cutii.
Și se leagă, de asemenea, stabilește un punct într-o relație.
Am alocat un bloc de memorie pe heap.
Observați că caseta din dreapta sus nu are un nume.
>> Am mallocd.
Care se află la grămadă.
Dar b are un nume.
Este o variabilă pointer numit b.
Care trăiește pe stiva.
>> Deci, este o bucată de memorie care indică la altul.
b conține adresa de care bloc de memorie.
Ea nu are un nume altfel.
Dar arată la ea.
Deci, atunci când spunem stea int b este egal cu Dimensiunea malloc de Int, că acolo,
că săgeata care a apărut cu privire la partea dreaptă acolo, că totul,
Voi avea să apară din nou, este ceea ce se întâmplă.
Toate acestea se întâmplă în că nicio linie de cod.
Acum vom avea ceva mai mult simplu din nou.
un egal ampersand m.
Îți amintești ce este egal cu ampersand m este?
Ei bine, asta-i o primeste adresa m lui.
Sau, mai schematic, de puncte de m.
>> are o valoare cuprinsă b.
OK Deci, aici este un alt unul.
Un egal cu b.
Ce se va întâmpla diagrama de data asta?
>> Ei bine, Amintiti-va ca Lucrari de operatori de atribuire
prin atribuirea valoarea de pe dreptul la valoarea din stânga.
Deci, în loc de o indicare a m, un acum subliniază în același loc pe care de puncte b.
o nu indică la B, o Puncte Puncte unde B.
>> În cazul în care un ascuțit la b care ar Au fost un egal cu ampersand b.
Dar, în loc un egal b doar înseamnă că și b sunt acum
arătând spre aceeași adresă, deoarece interior de b este doar o adresă.
Și acum în interiorul unei este aceeași adresă.
m este egal cu 10, probabil cea mai simplu lucru
am făcut într-un pic.
Pune 10 în caseta.
Stele b este egal cu m plus 2, amintesc de la indicii videoclipul nostru ceea ce înseamnă stea b.
Vom dereference b și a pus o valoare în acea locație de memorie.
În acest caz, 12.
>> Așa că atunci când am dereference un punct de amintesc ne-am deplasa în jos săgeată.
Sau, altfel spus, am du-te la acea adresă de memorie
si l-am manipula într-un fel.
Am pus o anumită valoare acolo.
În acest caz, stea b este egal cu m plus 2 este doar
du-te la variabila indicat de b, du-te la memorie indicat de b,
și a pus m plus 2 acolo, 12.
>> Acum am liber b.
Ce se întâmplă când liber b?
Amintiți-vă ce am spus mijloace gratuite.
Ce tot spun, atunci când am liber b?
>> Am terminat de lucru cu el, nu?
Dau în principal la memoria.
Am da înapoi în sistem.
Nu am nevoie de acest lucru mai este ceea ce eu le spun, bine?
>> Acum, dacă spun o stea este egal cu 11, puteți, probabil,
spune deja că ceva rău se va întâmpla aici, nu?
Și într-adevăr, dacă am încercat că probabil ar suferi o eroare de segmentare.
Deoarece acum, deși anterior ca bucată de memorie
a fost ceva ce am avut acces la, în acest moment
acum am acces la memorie care nu este legal pentru mine pentru a accesa.
>> Și, după cum, probabil, vom amintesc, atunci când am acces la memorie
că nu ar trebui să atingă, care este cea mai frecventa cauza
de o segmentare vina. Și așa programul meu
ar prăbuși dacă am încercat să fac acest lucru.
Deci, din nou, este o idee bună pentru a obține bun practici și obiceiuri bune înrădăcinată
atunci când se lucrează cu malloc și gratuit, astfel încât să nu suferă de segmentare
defecte, și pe care le utilizați dumneavoastră alocate dinamic
memorie responsabil.
>> Sunt Doug Lloyd este CS50.