[Musik spiller] DOUG LLOYD: OK, så et forslag før du starter her. Hvis du ikke har set videoen på pointere du måske ønsker at gøre det først. Da dette er en anden video måde at arbejde med pointere. Så det kommer til at tale om nogle begreber som vi dækker i pointere video, og vi er kommer til at glans over dem nu, under forudsætning af, at de er allerede slags forstået. Så det er bare din retfærdig advarsel at hvis du ser denne video og du har ikke set den pointers video, kan det slags flyve over dit hoved en lille smule. Og så kan det være bedre at se det i nævnte rækkefølge. Så vi har allerede set en måde at arbejde med pointere, som vi erklærer en variabel, og så vi Det fastslås en anden variabel, en pointer variabel, der peger på det. Så vi har oprettet en variabel med et navn, vi har skabt en anden variabel med et navn, og vi peger denne anden variabel på det første. Denne slags har en problem selv, fordi det kræver, at vi vide præcis hvor meget hukommelse er vi vil få brug for i øjeblikket vores program er kompileret. Hvorfor det? Fordi vi skal være i stand til at navngive eller identificere alle de mulige variabler vi kan støde på. Vi har måske et array, der kunne være stand til at holde en masse oplysninger, men det er stadig ikke præcis præcise nok. Hvad hvis vi ikke kender, hvad nu hvis vi ikke har nogen idé hvor meget vi har brug påkompileringstidspunktet? Eller hvad hvis vores program vil køre for en virkelig lang tid, acceptere forskellige bruger data, og vi kan ikke rigtig vurdere, om vi er vil få brug for 1.000 enheder? Det er ikke ligesom vi kan sige på kommandolinjen indtaste hvor mange elementer du tror, ​​du har brug for. Nå, hvad hvis det gæt er forkert? Dynamisk hukommelse tildeling slags giver os vej at omgå dette problem. Og den måde, det gør det er ved hjælp af pegepinde. Vi kan bruge pegepinde til få adgang til dynamisk allokeret hukommelse, hukommelse, der er fordelt som dit program kører. Det er ikke allokeret påkompileringstidspunktet. Når du dynamisk allokere hukommelse det kommer fra en pulje hukommelse kaldet dyngen. Tidligere al den hukommelse vi har arbejdet med i løbet har været kommer fra en pulje hukommelse kaldet stablen. En god måde at generelt holde mind-- og denne regel ikke altid holder stik, men temmelig meget næsten altid holder true-- er, at enhver gang du giver et variabelnavn det sandsynligvis bor på stakken. Og hver gang du ikke gør give en variabel et navn, som du kan gøre med dynamisk hukommelse tildeling, den lever på den bunke. Nu er jeg slags præsentere dette som hvis der er disse to puljer af hukommelse. Men du måske har set denne diagram, som generelt er en repræsentation af hvad hukommelse ser ud, og vi kommer ikke til at bekymre sig om alle stuff foroven og forneden. Hvad vi interesserer os, er denne del i midten her, dynge og stakken. Som du kan se ved ser på dette diagram, disse rent faktisk ikke er to separate puljer af hukommelse. Det er en fælles pool hukommelse hvor du starter, i denne visuelle du starter i bunden og begynde at fylde op fra bunden med stakken, og du starte øverst og begynde at fylde oppefra og ned med bunke. Men det er virkelig det samme pulje, det er bare forskellige steder, forskellige steder i hukommelsen, der bliver fordelt. Og du kan køre ud af hukommelse ved enten at have dyngen gå hele vejen til bunden, eller har stakken gå hele vejen til toppen, eller har dyngen og stakken mødes mod hinanden. Alle dem kan være betingelser der forårsager dit program at løbe tør for hukommelse. Så holder det i tankerne. Når vi taler om dyngen og stakken vi virkelig taler om samme generelle chunk hukommelse, lige forskellige dele af denne hukommelse. Så hvordan får vi dynamisk allokeret hukommelse i første omgang? Hvordan vores program får hukommelse som det kører? Nå C indeholder en funktion kaldet malloc, hukommelse fordelingsnøgle, som du foretage et opkald til, og du passere i hvor mange bytes af hukommelse, som du ønsker. Så hvis dit program kører og du vil have et heltal runtime, du måske Mallock fire byte hukommelse, malloc parenteser fire. Mallock vil gå gennem kigge gennem bunke, fordi vi er dynamisk tildeling af hukommelse, og det vil vende tilbage til dig en pointer til denne hukommelse. Det giver dig ikke at memory-- det ikke giver den et navn, det giver dig en pointer til det. Og så det er derfor igen sagde jeg at det er vigtigt at måske har set pejlemærker video før vi kommer for langt ind i dette. Så malloc kommer til at give dig tilbage en pegepind. Hvis Mallock ikke kan give dig nogen hukommelse, fordi du har kørt ud, det vil give dig tilbage en null-pointer. Kan du huske, hvad der sker, hvis vi Prøv og dereference en null pointer? Vi lider et seg fejl, ikke? Det er nok ikke godt. Så hver gang du foretager et opkald at malloc du altid, altid nødt til at tjekke, om den pointer det gav dig tilbage er null. Hvis det er, du skal ende dit program fordi hvis du prøver og dereference null pointer du vil til at lide en segmentering fejl og dit program er kommer til at gå ned alligevel. Så hvordan gør vi statisk opnå et heltal? int x. Vi har sikkert gjort, at en masse gange, ikke? Dette skaber en variabel kaldet x, der bor på stakken. Hvordan kan vi dynamisk at modtage et heltal? Int stjerne px lig malloc 4. Eller mere hensigtsmæssigt vi ville sige int stjerne px lig malloc størrelse int, bare at smide nogle færre magiske tal omkring vores program. Dette kommer til at opnå for os fire bytes hukommelse fra bunke, og pointeren vi får tilbage til det kaldes px. Og så ligesom vi har gjort tidligere vi kan dereference px til adgang til denne hukommelse. Hvordan får vi et heltal fra brugeren? Vi kan sige int x er lig få int. Det er temmelig ligetil. Hvad nu, hvis vi ønsker at skabe et array af x flåd, der lever på stakken? flyde stack_array-- det er navnet af vores array-- firkantede parentes x. Det vil skabe for os et array af x flåd, der lever på stakken. Vi kan skabe en række flydere der lever på den bunke, også. Syntaksen ser måske lidt mere besværligt, men vi kan sige float stjerne heap_array lig malloc x gange størrelsen af ​​flyderen. Jeg har brug for plads nok til at holde x floating point-værdier. Så siger jeg har brug for 100 flåd, eller 1.000 flåd. Så i dette tilfælde ville det være 400 bytes for 100 flåd, eller 4.000 bytes for 1.000 flåd, fordi hver float tager op fire bytes af plads. Efter at gøre dette, jeg kan bruge firkantede beslag syntaks på heap_array. Ligesom jeg ville på stack_array, jeg kan få adgang til individuelt dens elementer ved hjælp heap_array nul, heap_array én. Men huske årsagen til at vi kan gøre det skyldes, at navnet på et array i C er virkelig en pegepind til den opstilling første element. Så det faktum, at vi erklærer en vifte af svømmere på stakken her er faktisk en smule misvisende. Vi er virkelig i anden linje kode der skaber også en pointer til en bid af hukommelse, som vi så gøre noget arbejde med. Her er det store problem med dynamisk allokeret hukommelse selv, og det er derfor, det er virkelig vigtigt at udvikle nogle gode vaner når du arbejder med det. I modsætning til statisk erklæret hukommelse, din hukommelse ikke automatisk tilbage til system, når din funktion er færdig. Så hvis vi har vigtigste, og vigtigste kalder en funktion f, når f finish uanset hvad den gør og returnerer kontrol af programmet tilbage til main, alle af hukommelsen at f anvendt gives tilbage. Det kan bruges igen af et andet program, eller en anden funktion, bliver kaldt senere i main. Det kan bruge den samme hukommelse igen. Hvis du dynamisk allokere hukommelse selv du er nødt til eksplicit at fortælle system, som du er færdig med det. Det vil holde på det for dig, som kunne føre til et problem af jer løbe ud hukommelse. Og i virkeligheden vi nogle gange henvise til dette som en hukommelsesfejl. Og undertiden disse hukommelseslækager kan faktisk være virkelig ødelæggende for systemydelse. Hvis du er en hyppig internetbruger du kan bruge visse webbrowsere, og jeg vil ikke nævne navne her, men der er nogle webbrowsere derude der er berygtet for faktisk at have memory leaks, der ikke få fast. Og hvis du lader din browser åben for en meget lang periode, dage og dage, eller uger, du nogle gange måske bemærke, at dit system kører virkelig, virkelig langsomt. Og grunden til det er, at browseren har afsat hukommelse, men så ikke fortalt systemet at det er gjort med det. Og så efterlader mindre hukommelse tilgængelig for alle dine andre programmer at skulle dele, fordi du er leaking-- at web browser Programmet er utæt hukommelse. Hvordan giver vi hukommelse tilbage når vi er færdig med den? Nå heldigvis er det en meget let måde at gøre det. Vi har lige frigøre det. Der er en funktion kaldet fri, den accepterer en pegepind til hukommelsen, og vi er gode til at gå. Så lad os sige, vi er i midt i vores program, vi ønsker at malloc 50 tegn. Vi ønsker at allokere et array, der kan stand til at holde 50 tegn. Og når vi får en pointer tilbage til at, det pointer navn er ord. Vi gør, hvad vi er vil gøre med ord, og så når vi er gjort vi bare frigøre det. Og nu har vi vendt tilbage dem 50 bytes hukommelse tilbage til systemet. En anden funktion kan bruge dem. Vi behøver ikke at bekymre dig om at lide et hukommelsesfejl fordi vi har befriet ord. Vi har givet hukommelsen tilbage, så vi er færdig at arbejde med det. Så der er tre gyldne regler, der bør holdes for øje, når du er dynamisk allokering hukommelse med malloc. Hver blok af hukommelse, du malloc skal frigøres før dit program er færdig kører. Nu igen, i apparatet eller i IDE denne slags sker for dig alligevel når du-- dette vil ske alligevel når dit program er afsluttet, alle hukommelsen vil blive frigivet. Men det er generelt god kodning praksis altid, når du er færdig, frigøre hvad du har mallocd. Det er sagt, eneste ting, du har mallocd bør befries. Hvis du statisk erklære en heltal, int x semikolon, der lever på stakken, du ikke så ønsker at frigøre x. Så eneste ting, som du har mallocd bør befries. Og endelig, ikke gratis noget to gange. Der kan føre til anden underlig situation. Så alt, hvad du har mallocd skal frigøres. Kun ting, som du har malloc bør befries. Og gør ikke gratis noget to gange. Så lad os gå gennem et eksempel her af, hvad nogle dynamisk allokeret hukommelse kunne ligne blandet i med nogle statisk hukommelse. Hvad der kan ske her? Se om du kan følge sammen og gæt, hvad der er kommer til at ske, når vi går gennem alle disse linjer kode. Så vi siger int m. Hvad sker der her? Nå det er temmelig ligetil. Jeg skaber et heltal variabel kaldet m. Jeg farve det grønne, fordi det er den farve at jeg bruger, når jeg taler om heltalsvariabler. Det er en kasse. Det kaldes m, og du kan gemme heltal inde i den. Hvad hvis jeg så sige int stjerne en? Nå det er temmelig ens. Jeg skaber en kasse kaldes en. Det er stand til at holde int stjerner, pegepinde til heltal. Så jeg farve det grønne-ish så godt. Jeg ved, det har noget at gøre med et heltal, men det er ikke i sig selv et heltal. Men det er stort set den samme idé. Jeg har oprettet en kasse. Begge disse ret nu bor på stakken. Jeg har givet dem begge navne. int stjerne b lig malloc størrelse int. Denne ene kan være lidt tricky. Tag en anden og tænke over, hvad du ville forvente at ske på dette diagram. int stjerne b lig malloc størrelse int. Nå dette ikke bare oprette en boks. Dette faktisk opretter to bokse. Og det binder det også etablerer et punkt i et forhold. Vi har afsat en blok hukommelse på bunke. Bemærk at det øverste højre boks der ikke har et navn. Vi mallocd det. Det findes på den bunke. Men b har et navn. Det er en pointer variabel kaldet b. Der lever på stakken. Så det er et stykke af hukommelse der peger på en anden. b indeholder adressen af denne blok hukommelse. Det har ikke et navn andet. Men den peger på den. Så når vi siger int stjerne b lig malloc størrelse int, at lige der, at pil, der dukkede op på højre side er der, det hele, Jeg vil gerne have det ud igen, er, hvad der sker. Alt dette sker i at eneste linje kode. Nu får vi lidt mere ligetil igen. et lig tegnet m. Kan du huske, hvad en lig tegnet m er? Tja, der er en får m adresse. Eller sagt mere skematisk, a peger på m. a er lig med b. OK, så her er en anden. A er lig med b. Hvad kommer til at ske til diagrammet denne gang? Nå minde om, at tildelingsoperatoren værker ved at tildele værdien på ret til værdien til venstre. Så i stedet for en pegende til m, en nu peger på det samme sted, b point. en ikke pege på B, A peger hvor b point. Hvis en spids til b, som ville har været en lig tegnet b. Men i stedet en lig b bare betyder, at og b er nu peger på den samme adresse, fordi indersiden af ​​b er blot en adresse. Og nu inde i en er den samme adresse. m er lig med 10, formentlig den mest ligefremme ting vi har gjort i en lille smule. Sæt 10 i boksen. Stjerne b er lig m plus 2, husker fra vores pejlemærker video hvad stjerne b betyder. Vi kommer til at dereference b og put vis værdi i at hukommelsesplads. I dette tilfælde 12. Så når vi dereference et punkt husker vi bare rejse ned pilen. Eller sagt på en anden måde, vi gå til at hukommelsen adresse og vi manipulere den på en eller anden måde. Vi sætter en vis værdi derinde. I dette tilfælde stjerne b lig m plus 2 er lige gå til den variable peget på af b, gå til hukommelsen peget på af b, og sætte m plus 2 derinde, 12. Nu jeg fri b. Hvad sker der, når jeg fri b? Husk, hvad jeg sagde frie midler. Hvad skal jeg sige, når jeg fri b? Jeg er færdig at arbejde med det, ikke? Jeg hovedsagelig opgive hukommelsen. Jeg giver den tilbage til systemet. Jeg har ikke brug for dette længere er hvad jeg fortæller dem, OK? Nu, hvis jeg siger stjerne en lig 11 kan du sikkert allerede fortælle, at noget slemt kommer til at ske her, ikke? Og faktisk, hvis jeg forsøgte at jeg nok ville lide en segmentering fejl. Fordi nu, selv om tidligere, at bid af hukommelse var noget, som jeg havde adgang til, på dette tidspunkt nu er jeg adgang til hukommelse, er ikke lovligt for mig at få adgang til. Og som vi vil sandsynligvis husker, når vi adgang hukommelse at vi ikke er formodes at røre, det er den mest almindelige årsag af en segmentering fejl. Og så mit program ville gå ned, hvis jeg forsøgte at gøre dette. Så igen er det en god idé at få god praksis og gode vaner indgroet når du arbejder med malloc og fri, så du ikke lider segmentering fejl, og at du bruger din dynamisk allokeret hukommelse ansvarligt. Jeg er Doug Lloyd dette er CS50.