[Prehrávanie hudby] DOUG LLOYD: OK, takže návrh, Pred spustením tu. Ak ste sledovali video na na ukazovatele budete chcieť robiť tak ako prvý. Vzhľadom k tomu, toto video je ďalší spôsob práce s ukazovateľmi. Takže to bude hovoriť o niektorých pojmov že budeme rozprávať v na ukazovatele videá, a my sme bude lesk nad nimi teraz, za predpokladu, že sú už tak nejako pochopil. Tak to je len váš fér varovanie že ak ste videl toto video a vy ste nevideli ukazovatele video, by to mohlo nejako lietať nad hlavou, trochu. A tak by to mohlo byť lepšie sa pozerať na to v tomto poradí. Takže sme už videli jeden spôsob práce s ukazovateľmi, čo je deklarujeme variabilná, a potom sme deklarovať ďalšie premennú, ukazovateľ premenná, ktorá ukazuje na to. Preto sme vytvorili premenná s názvom, máme vytvoril druhú premennú s názvom, a upozorňujeme, že Druhá premenná na to ako prvý. Tento druh má Problémom však, pretože to vyžaduje, aby sme presne vedeli, koľko pamäti, že sme bude potrebovať vo chvíli, Náš program je zostavený. Prečo tomu tak je? Vzhľadom k tomu, musíme byť schopní pomenovať alebo identifikovať všetky možné premenných môžeme stretnúť. Mohli by sme mať pole, ktoré by mohlo byť schopný pojať veľké množstvo informácií, ale je to stále nie je presne dostatočne presná. Čo keď nevieme, čo keď budeme mať tušenie koľko budeme potrebovať v čase kompilácie? Alebo čo keď náš program bude bežať naozaj dlhú dobu, prijímať rôzne užívateľa dát, a môžeme naozaj odhadnúť, či sme bude potrebovať 1000 kusov? Nie je to tak, môžeme hovoria, na príkazovom riadku Zadajte, koľko položiek si myslíte, že budete potrebovať. No čo ak odhad je zle? Dynamické prideľovanie pamäte druh umožňuje nám cestu obísť tento konkrétny problém. A to, ako to robí je pomocou ukazovateľov. Môžeme použiť odkazy na získať prístup k dynamicky pridelenej pamäti, pamäti, ktorá je pridelený ako váš program beží. Nie je to pridelené v čase kompilácie. Keď dynamicky prideľovať Pamäť pochádza z bazéna pamäte známy ako haldy. Skôr je celá pamäť máme pracuje sa v priebehu bol pochádzajúce z bazéna pamäte známy ako zásobníka. Dobrým spôsobom, ako všeobecne majte na mind-- a tomto pravidle nemusí vždy platiť, ale do značnej miery takmer vždy myslí true-- je, že každý čas si dať názov premennej it pravdepodobne žije na zásobníku. A zakaždým, keď nie vykazovať premenlivú meno, ktoré môžete robiť s dynamickej pamäte alokácie, žije na halde. Teraz som trochu prezentovať to ako v prípade, že je tieto dva bazény pamäti. Ale možno videli toto diagram, ktorý je všeobecne znázornenie Aké pamäťové vyzerá, a nebudeme sa starať o všetkom Hmota v hornej a dolnej časti. To, čo zaujíma je táto časť v prostredný tu, haldy a zásobník. Ako môžete vidieť pri pohľade na tomto diagrame, Tieto skutočnosti nie sú dvoch oddelené bazény pamäte. Je to jedna spoločná pool pamäte kde začať, v tomto vizuálne začnete v dolnej časti a začať vyplnenie od dna s zásobníka, a vy začínajú na hornej a začatie doplňovanie zhora nadol s haldy. Ale je to naozaj je Rovnaký bazén, je to len rôznych miestach, rôzne umiestnenia v pamäti, ktoré sú pridelené. A môžete dôjdu pamäť buď s halda ísť celú cestu ku dnu, alebo sa zásobníka ísť celú cestu na vrchol, alebo má haldy a zásobníka stretnúť sa proti sebe. Všetky z nich môžu byť podmienky ktoré spôsobujú program spustiť nedostatok pamäte. Takže majte na pamäti, že. Keď hovoríme o halda a zásobník sme naozaj hovoríme o rovnakej všeobecnej kus pamäti, len rôzne časti tejto pamäte. Tak ako sa dostaneme dynamicky pridelené pamäte v prvom rade? Ako sa dostať náš program pamäť, ako to beží? No C poskytuje funkciu nazvanú malloc, pamäť alokátor, ktorý voláte na, a tie odovzdať koľko bajtov pamäte, ktoré chcete. Takže ak váš program beží a chcete integer runtime, môžete Mallock štyri byty pamäť, malloc zátvorky štyri. Mallock prejde hľadá cez haldy, pretože sme dynamicky prideľovanie pamäte, a navrátim sa k vám ukazovateľ na tejto pamäti. To nedáva vám, že memory-- nedáva to meno, to vám dáva ukazovateľ na neho. A tak to je dôvod, prečo som zase povedal, že je dôležité možná Sledoval ukazovatele videá než sa dostaneme príliš ďaleko do toho. Tak malloc to bude vám späť ukazovateľ. Ak Mallock nemôže dať vám niektorý pamäť, pretože ste dôjdu, to bude vám späť ukazovatele null. Pamätáš si, čo sa stane, keď vyskúšať a dereferencia null ukazovateľ? Trpíme poruchu seg, že jo? To je asi nie je dobré. Takže zakaždým, keď voláte vás malloc vždy, vždy je potrebné overiť, či je alebo nie je ukazovateľ, že vám dal späť, je null. Ak áno, budete musieť ukončiť svoj program pretože ak sa pokúsite a dereferencia ukazovatele null budete trpieť poruchy segmentácie a váš program je spadne tak ako tak. Tak ako sme staticky získať celé číslo? int x. Sme pravdepodobne urobil banda z časov, je to tak? To vytvára premennú s názvom x, ktorá žije v zásobníku. Ako môžeme dynamicky získať číslo? Int hviezda px rovná malloc 4. Alebo viac vhodne by sme povedať, int hviezda px rovná malloc veľkosť int, len hodiť niektoré menej Magická čísla okolo nášho programu. To sa chystá získať pre nás Štyri bajtov pamäte z haldy, a ukazovateľ dostaneme späť k nej, sa nazýva px. A potom už len ako my máme vykonané už skôr sme môže dereferencia PX prístup k tejto pamäte. Ako môžeme získať celé číslo od užívateľa? Dá sa povedať, int x rovná sa dostať int. To je celkom jednoduché. Čo ak chceme vytvoriť pole z x plaváky, ktoré žijú vo fronte? float stack_array--, že sa volá z našich array-- hranatých zátvoriek x. To bude vytvárať pre nás poľa z x plaváky, ktoré žijú v zásobníku. Môžeme vytvoriť celý rad plavákov ktorá žije na halde, taky. Syntax môže vyzerať trochu ťažkopádne, ale môžeme povedať, float hviezda heap_array rovná malloc x meria veľkosť plaváku. Potrebujem dostatok priestoru držať x s plávajúcou desatinnou čiarkou hodnoty. Takže povedať, že som potrebovať 100 plaváky, alebo plaváky 1000. Takže v tomto prípade by bolo 400 bytov pre 100 plaváky, alebo 4000 bajtov na 1000 plaváky, pretože každý float zaberá štyri byty priestoru. Potom, čo to môžem použiť hranatou zátvorku syntax na heap_array. Rovnako ako by som na stack_array, ja môžu individuálne pristupovať k jej prvky pomocou heap_array nula, heap_array jednu. Ale spomínam, prečo to môžeme urobiť Je tomu tak preto názov poľa v C je naozaj ukazovateľ na Prvý prvok tejto matice je. Takže k tomu, že sme deklarovaní rad plavákov na zásobníku tu je vlastne trochu zavádzajúce. Sme naozaj v Druhý riadok kódu tam tiež vytvára ukazovateľ na kus pamäti, že sme potom urobiť nejakú prácu s. Tu je veľký problém s dynamicky pridelenej pamäti však, a to je dôvod, prečo je to naozaj dôležité vytvoriť nejaké dobré návyky pri práci s ním. Na rozdiel od staticky deklaroval pamäť, pamäť nie je automaticky vrátená do Systém, kedy je vaša funkcia vykonáva. Takže ak máme hlavné, a Hlavný volá funkciu f, keď f povrchovej úpravy ako sa to robí a vráti riadenie programu späť na hlavnú, všetky pamäte že f použiť, je vrátená späť. To môže byť znovu použitý nejakým iným programom, alebo nejaké iné funkcie, ktorá sa zavolá neskôr v main. Je možné používať rovnako pamäť opäť nad. Ak vás dynamicky alokovať pamäť hoci budete musieť povedať, systém, ktorý ste s ním urobil. Bude to držať to pre vás, ktoré by mohli vedú k problému z vás beží pamäte. A v skutočnosti sme niekedy sa odvolávajú na toto ako pretekanie pamäte. A niekedy tieto pretekanie pamäte môže byť v skutočnosti naozaj zničujúce na výkon systému. Ak ste častým používateľ internetu môžete použiť niektoré webové prehliadače, a nebudem tu menovať mená, ale tam sú niektoré webové prehliadače vonku ktoré sú notoricky známe pre skutočne majú úniky pamäte, ktoré nie sú opravené. A ak necháte Váš prehliadač otvorené Po veľmi dlhú dobu, dni a dni, alebo týždne, niekedy všimnúť, že vo vašom systéme beží naozaj, ale naozaj pomaly. A dôvod pre to je skutočnosť, že prehliadač má pridelené pamäti, ale potom nepovedal systém že sa to robí s ním. A tak, že opustí menej pamäte k dispozícii pre všetky vaše iných programov musieť podeliť, pretože si leaking--, že webový prehliadač Program je netesní pamäte. Ako môžeme dať pamäť späť keď sme s ním urobil? No našťastie je to veľmi jednoduchý spôsob, ako to urobiť. Práve sme ho uvoľniť. K dispozícii je funkcia nazvaná zdarma, prijíma ukazovateľ na pamäti, a my sme dobré ísť. Takže povedzme, že sme v Uprostred nášho programu, Chceme malloc 50 znakov. Chceme malloc pole, ktoré môže schopné pojať 50 znakov. A keď sa dostaneme ukazovateľ späť že názov cez tento ukazovateľ je slovo. Robíme, čo máme robiť s slovu, a potom, keď sme urobili sme jednoducho ho uvoľniť. A teraz sme sa vrátili tie 50 bajtov pamäti späť do systému. Niektoré ďalšie funkcie môžu používať. Nemusíme sa starať o utrpení pretekanie pamäte, pretože sme oslobodení slovo. Dali sme pamäť späť, takže sme skončili prácu s ním. Takže tam sú tri zlatých pravidiel, ktorá by mala Treba mať na pamäti vždy, keď budete dynamicky prideľovanie pamäte s malloc. Každý blok pamäte, ktorá vy malloc musí byť uvoľnený Pred programu dokončenie spustenia. Teraz opäť do spotrebiča alebo v IDE tento druh stane pre vás tak ako tak kedy vás-- sa to stane tak ako tak ak je váš program ukončený, celá pamäť sa uvoľní. Ale je to všeobecne dobrá kódovanie praxe vždy, keď budete hotoví, oslobodiť, čo ste mallocd. To znamená, že len veci, ktoré nemáš mallocd by mal byť oslobodený. Ak staticky deklarovať integer, int x bodkočiarka, ktorá žije na zásobníku, budete nemajú potom chcieť oslobodiť x. Takže len veci, ktoré ste mallocd by mal byť oslobodený. A konečne, nie voľné niečo dvakrát. To môže viesť k ďalšie divná situácia. Takže všetko, čo som mallocd musí byť oslobodený. Iba veci, ktoré ste si malloc by malo byť uvoľnené. A nie bez niečo dvakrát. Takže poďme prejsť príklad tu z toho, čo niektorí dynamicky pridelenej Pamäť môže vyzerať ako zmiešané v s nejakým statické pamäte. Čo by sa mohlo stať tu? Uvidíme, či môžete sledovať spolu, a hádajte, čo je sa stane, ako sme ísť cez všetky tieto riadky kódu. Takže hovoríme int m. Čo sa tu deje? No to je celkom jednoduché. Aj vytvoriť celočíselnú premennú s názvom m. Aj farba je zelená, pretože to je farba ktorý používam, keď hovorím o celočíselné premenné. Je to krabice. Hovorí sa tomu m, a môžete ukladať celé čísla vnútri neho. Čo keď som potom povedal int hviezdičkou? No to je dosť podobné. Som vytvoriť krabice volal. Je schopná pojať int hviezdy, ukazovatele na celé čísla. Takže som to farbenie Green-ish rovnako. Viem, že to má niečo čo do činenia s celým číslom, ale to nie je samo o sebe celé číslo. Ale je to skoro rovnaké nápad. Vytvoril som krabicu. Obe tieto práva teraz žijú na zásobníku. Ja som im dal obe mená. int hviezda b rovná malloc veľkosť int. Toto by mohlo byť trochu zložitejšie. Vezmite druhý a premýšľať o tom, čo by sa očakávať, že sa stane v tejto schéme. int hviezda b rovná malloc veľkosť int. No to nie je len vytvoriť jednu kolónku. Toto vlastne vytvára dve krabice. A to väzby, ale tiež stanovuje bod vo vzťahu. Máme pridelené jeden blok pamäte na halde. Všimnite si, že v pravom hornom rohu box tam nemá meno. Mallocd sme to. To existuje na halde. Ale b má meno. Je to ukazovateľ premennú s názvom b. Ktorá žije na zásobníku. Takže je to kus pamäte , Ktorý odkazuje na iný. b obsahuje adresu z tohto bloku pamäte. Nemá meno inak. Ale to poukazuje na to. Takže keď povieme int star b sa rovná Veľkosť malloc int, že práve tam, že šípka, ktorá vyskočila na pravá strana tam, že celá tá vec, Budem mať to vyzerať Znovu, je to, čo sa stane. To všetko sa deje v že jediný riadok kódu. Teraz budeme mať trochu viac priamočiare znova. A je rovná ampersand m. Spomínate si, čo si rovná ampersand m je? No to je dostane adresu M. Alebo dať viac schematicky, A ukazuje na m. A je rovná b. OK, takže tu je ďalší. A je rovná b. Čo sa bude diať diagramu tentoraz? No pripomenúť, že Operátor priradenie práce priradením hodnoty na strane právo na hodnotu vľavo. Takže namiesto toho, ukazovacie do m, je teraz poukazuje na rovnakom mieste, ktoré b bodov. neukazuje na B, A miesta, kde sa b bodov. Ak sa ukázal na B, ktorá by boli sa rovná ampersand b. Ale namiesto toho sa rovná b len Znamená to, že a a b sú teraz smerujúce na rovnakú adresu, pretože vnútri b je len adresa. A teraz vo vnútri a je rovnaká adresa. m sa rovná 10, pravdepodobne Najjednoduchšia vec urobili sme v trochu. Dajte 10 v krabici. Hviezda b sa rovná m plus 2, prevezme späť od náš ukazovatele video Čo hviezda b znamená. Budeme dereferencia b a put nejakú hodnotu v tomto pamäťovom mieste. V tomto prípade 12. Takže keď sme sa dereferencia bodu spomínam len sme cestovať dole na šípku. Inak povedané, my choďte na túto adresu pamäti a my sme s ním manipulovať nejakým spôsobom. Dali sme nejakú hodnotu tam. V tomto prípade hviezdičkový B M rovné plus 2 je jednoducho ísť do premennej ukázal na B, prejsť do pamäte ukázal na B, a dal m plus 2 tam, 12. Teraz som oslobodiť b. Čo sa stane, keď som sa oslobodiť b? Spomeňte si, čo som povedal, voľné prostriedky. Čo som povedal, keď som sa oslobodiť b? Skončil som s ňou pracovať, nie? Ja v podstate vzdať pamäti. Dávam ju späť do systému. Nepotrebujem to už je to, čo som im povedal, OK? Teraz, keď poviem hviezdičkou sa rovná 11 môžete pravdepodobne Už, že niečo zlé povedať, sa stane, že? A skutočne, keď som sa snažil, že by som asi by utrpela chybu segmentácie. Vzhľadom k tomu, teraz, aj keď predtým, že kus pamäte bolo niečo, čo som mal prístupu k nim v tomto bode teraz som prístup k pamäti, že nie je legálne pre mňa prístup. A ako budeme pravdepodobne spomínate, keď sme sa prístup k pamäti že sme nemali na dotyk, to je najčastejšou príčinou z segmentácia porucha. A tak sa môj program zrúti, keď som sa snažil to urobiť. Takže opäť je to dobrý nápad, aby si dobre praxe a dobré návyky hlboko zakorenené Pri práci s malloc a zadarmo, takže nemusíte trpieť segmentáciu chyby, a že používate vaše dynamicky pridelenej pamäť zodpovedne. Som Doug Lloyd je to CS50.