[Speel van musiek] DOUG LLOYD: OK so 'n voorstel voordat hier begin. As jy die video op nie gekyk Pointers jy dalk wil om dit eerste te doen. Omdat hierdie video is nog manier van werk met wysers. So dit gaan om te praat oor 'n paar konsepte dat ons in die dek Pointers video, en ons is gaan glans oor hulle nou, die veronderstelling dat hulle reeds soort van verstaan. So dit is net jou eerlike waarskuwing dat as jy sien jy hierdie video en jy nie gesien het nie die wysers video, kan dit soort van vlieg oor jou kop 'n bietjie. En so is dit dalk beter wees om dit te sien in daardie volgorde. So het ons reeds een gesien manier om te werk met wysers, wat is ons verklaar 'n veranderlike, en dan sal ons verklaar 'n ander veranderlike, 'n wyser veranderlike, wat verwys na dit. Dus het ons het 'n veranderlike met 'n naam, het ons het 'n tweede veranderlike met 'n naam, en ons wys dat die tweede veranderlike op daardie eerste. Hierdie soort van 'n probleem is egter, want dit vereis dat ons weet presies hoeveel geheue ons gaan die oomblik nodig ons program word saamgestel. Hoekom is dit? Want ons moet in staat wees om te noem of identifiseer al die moontlike veranderlikes Ons kan teëkom. Ons kan 'n verskeidenheid wat dalk het in staat wees om 'n baie inligting te hou, maar dit is nog nie presies presies genoeg. Wat gebeur as ons nie weet nie, wat as ons het geen idee hoeveel ons nodig het tydens kompilering? Of wat as ons program sal hardloop vir 'n baie lang tyd, aanvaar verskillende gebruikers data, en ons kan nie regtig skat of ons gaan 1000 eenhede nodig? Dit is nie soos ons kan sê op die opdrag lyn Tik hoeveel items jy dink jy nodig het. Wel, wat as dit raaiskoot is verkeerd? Dinamiese geheuetoekenning soort van laat ons die weg te kry om hierdie spesifieke probleem. En die manier waarop dit werk dit is deur die gebruik van verwysings. Ons kan verwysings na gebruik kry toegang tot dinamiese toegeken geheue, geheue wat as jou program toegeken is hardloop. Dit is tydens kompilering nie toegeken. Wanneer jy dinamiese toewys geheue dit kom uit 'n poel geheue bekend as die hoop. Voorheen al die geheue ons het is besig met die kursus in is afkomstig van 'n poel geheue bekend as die stapel. 'N goeie manier om in die algemeen in mind-- en hierdie reël te hou nie altyd hou waar, maar pretty much byna altyd hou true-- is dat enige tyd wat jy 'n veranderlike naam gee waarskynlik woon op die stapel. En enige tyd wat jy dit nie doen nie gee 'n veranderlike 'n naam, wat jy kan doen met 'n dinamiese geheue toekenning, dit leef op die hoop. Nou is ek soort van die aanbieding van hierdie as as daar hierdie twee poele van die geheue. Maar jy kan dit gesien het diagram, wat is oor die algemeen 'n voorstelling van wat geheue lyk, en ons is nie van plan om oor al omgee die dinge op die bokant en die onderkant. Wat ons omgee is hierdie deel in die middel hier, hoop en stapel. Soos jy kan sien deur kyk na hierdie diagram, hierdie eintlik is nie twee aparte swembaddens van die geheue. Dit is een van die geheue shared pool waar jy begin, in hierdie visuele jy begin aan die onderkant en begin vul van die onderkant met die stapel, en jy begin by die top en begin vul uit die top-down met die hoop. Maar dit is regtig die dieselfde swembad, dit is net verskillende plekke, verskillende plekke in die geheue wat toegeken word. En jy kan uit te voer geheue deur óf met die hoop gaan al die pad aan die onderkant, of die stapel gaan al die pad na die top, of met die hoop en die stapel ontmoet teen mekaar. Al daardie kan voorwaardes dat jou program veroorsaak uit geheue uit te voer. So hou dit in gedagte. Wanneer ons praat oor die hoop en die stapel Ons is regtig praat oor die dieselfde algemene deel van die geheue, net verskillende gedeeltes van daardie geheue. So hoe kry ons dinamiese geheue toegeken in die eerste plek? Hoe ons program te kry geheue as dit loop? Wel C bied 'n funksie genoem malloc, geheue allocator, wat jy 'n oproep te maak, en jy slaag in hoeveel bytes geheue wat jy wil. So as jou program loop en jy wil 'n heelgetal runtime, jy dalk mallock vier grepe van geheue, malloc hakies vier. mallock gaan deur soek deur die hoop, want ons is dinamies toekenning geheue, en dit sal na julle terugkeer 'n verwysing na wat die geheue. Dit gee jou nie dat memory-- dit nie gee dit 'n naam, dit gee jou 'n wyser om dit te. En so dit is hoekom ek weer sê dat dit belangrik is om dalk die wysers video gekyk voordat ons te ver na hierdie. So malloc gaan gee jou terug 'n wyser. As jy mallock nie kan gee geheue omdat jy uit gehardloop het, dit gee jou terug 'n null pointer. Onthou jy wat gebeur as ons probeer dereference n null pointer? Ons ly onder 'n seg skuld, reg? Dit is waarskynlik nie goed nie. So elke keer as jy 'n oproep te maak om julle altyd malloc, altyd nodig om te kyk of die aanwijzer dit het jy terug is van nul. As dit is, moet jy jou program eindig want as jy probeer en dereference die nul pointer jy gaan 'n segmentering skuld ly en jou program is gaan in elk geval crash. So hoe kan ons staties kry 'n heelgetal? int x. Ons het waarskynlik gedoen 'n klomp van die tye, reg? Dit skep 'n veranderlike genoem x wat leef op die stapel. Hoe weet ons dinamiese 'n heelgetal te verkry? Int star px gelyk malloc 4. Of meer toepaslik ons wil sê int star px gelyk malloc grootte van int, net 'n paar minder gooi magic nommers om ons program. Dit gaan kry vir ons vier grepe van die geheue van die hoop, en die wyser kry ons terug na dit genoem px. En dan, net soos ons het voorheen gedoen ons kan dereference px om toegang wat die geheue. Hoe kry ons 'n heelgetal van die gebruiker? Ons kan sê int x gelyk te kry int. Dit is redelik eenvoudig. Wat as ons wil 'n skikking te skep van x dryf wat lewe op die stapel? dryf stack_array-- dit is die naam van ons array-- vierkantige hakies x. Dit sal skep vir ons 'n skikking van x dryf wat lewe op die stapel. Ons kan 'n verskeidenheid van dryf skep wat leef op die hoop, ook. Die sintaksis kan kyk 'n bietjie meer omslagtig, maar ons kan float sê star heap_array gelyk malloc x keer die grootte van die float. Ek moet genoeg ruimte om te hou x drywende punt waardes. So sê ek moet 100 dryf, of 1000 dryf. So in daardie geval sal dit 400 grepe vir 100 dryf, of 4000 grepe vir 1000 dryf, want elke float neem vier grepe van die ruimte. Nadat dit te doen wat ek kan gebruik om die vierkante bracket sintaksis op heap_array. Net soos ek sou op stack_array, ek kan sy elemente individueel toegang gebruik van heap_array nul, heap_array een. Maar onthou die rede kan ons dit doen is omdat die naam van 'n skikking in C is regtig 'n wyser na dat array eerste element. So die feit dat ons 'n verklaring verskeidenheid van dryf op die stapel hier is eintlik 'n bietjie misleidend. Ons werklik is in die tweede lyn van die kode is daar skep ook 'n verwysing na 'n stuk van geheue dat ons dan 'n paar werk met te doen. Hier is die groot probleem met dinamiese toegeken geheue alhoewel, en dit is die rede waarom dit is regtig belangrik om 'n paar goeie gewoontes te ontwikkel wanneer jy werk met dit. Anders staties verklaar geheue, jou geheue word nie outomaties terug na die stelsel as jou funksie word gedoen. So as ons belangrikste en hoof noem 'n funksie f, toe f afwerkings wat dit doen en opgawes beheer van die program Terug na die hoof, almal van die geheue f gebruik word terug gegee. Dit kan weer gebruik word deur 'n ander program, of 'n ander funksie wat kry genoem later in die belangrikste. Dit kan dieselfde geheue weer te gebruik oor. As jy dinamies toeken geheue al jy het om uitdruklik vertel die stelsel wat jy klaar is met dit. Dit sal vashou dit vir jou, wat kan lei tot 'n probleem van julle loop uit van die geheue. En in die feit dat ons soms verwys om dit as 'n geheue lek. En soms hierdie geheue lekkasies eintlik kan regtig verwoestende vir prestasie-stelsel. As jy 'n gereelde internet gebruikers jy kan gebruik sekere webblaaiers, en Ek sal nie hier name noem nie, maar daar is 'n paar webblaaiers daar buite wat berug vir eintlik het is geheue lekkasies wat nie vaste kry. En as jy laat jou browser oop vir 'n baie lang tydperk van die tyd, dae en dae of weke, het jy soms dalk agterkom dat jou stelsel is loop regtig, regtig stadig. En die rede daarvoor is dat die leser het geheue toegeken, maar dan nie die stelsel het dat dit gedoen is met dit. En sodat minder geheue laat beskikbaar vir al jou ander programme om te deel, want jy is leaking-- dat webblaaier program lek geheue. Hoe gee ons geheue terug wanneer ons klaar is met dit? Wel gelukkig is dit 'n baie maklike manier om dit te doen. Ons bevry is dit net. Daar is 'n funksie genoem vry, dit 'n wyser aanvaar om die geheue, en ons is goed om te gaan. So kom ons sê ons is in die middel van ons program, ons wil 50 karakters malloc. Ons wil 'n skikking wat kan malloc staat van die hou van 50 karakters. En wanneer ons 'n wyser terug na dat die naam van die wyser is woord. Ons doen wat ons gaan doen met die woord, en dan wanneer ons gedoen wat ons bevry is dit net. En nou het ons teruggekeer diegene 50 grepe van die geheue terug na die stelsel. 'N ander funksie kan gebruik. Ons hoef nie te bekommerd wees oor die lyding van 'n geheugenlek omdat ons woord bevry. Ons het die geheue terug gegee, sodat ons klaar besig met dit. So is daar drie goue reëls dat indien in gedagte gehou word wanneer jy dinamiese toekenning geheue met malloc. Elke blok geheue wat jy moet malloc bevry voor jou program afwerkings hardloop. Nou weer in die toestel of in die IDE hierdie soort van gebeur vir jou in elk geval wanneer you-- dit in elk geval sal gebeur Wanneer jou program is beëindig, al die geheue vrygestel sal word. Maar dit is oor die algemeen goed kodering praktyk om altyd, wanneer jy klaar is, bevry wat jy mallocd. Dit gesê, enigste dinge wat jy het mallocd moet bevry. As jy 'n staties verklaar heelgetal, int x semi-kolon, wat leef op die stapel, jy nie dan wil bevry x. So enigste dinge wat jy het mallocd moet bevry. En laastens, moenie gratis iets twee keer. Wat kan lei tot 'n ander vreemde situasie. So alles wat jy het mallocd moet bevry. Enigste dinge wat jy het malloc moet bevry. En doen nie vry iets twee keer. So laat ons gaan deur 'n voorbeeld hier van wat sommige dinamiese toegeken geheue kan lyk gemengde met 'n paar statiese geheue. Wat kan hier gebeur? Kyk of jy kan volg saam en raai wat is gaan gebeur as ons gaan deur al hierdie reëls van die kode. So sê ons int m. Wat gebeur hier? Wel, dit is redelik eenvoudig. Ek skep 'n heelgetal veranderlike genoem m. Ek kleur dit groen, want dit is die kleur wat ek gebruik wanneer ek praat oor heelgetal veranderlikes. Dit is 'n boks. Dit is bekend m, en jy kan heelgetalle winkel binnekant van dit. Wat gebeur as ek dan sê int star a? Wel, dit is redelik soortgelyk. Ek is die skep van 'n boks genoem. Dit is in staat om van hou int sterre, verwysings na heelgetalle. So ek kleur dit groen-ish as well. Ek weet dit het iets te doen het met 'n heelgetal, maar dit is nie self 'n heelgetal. Maar dit is pretty much dieselfde idee. Ek het 'n boks geskep. Beide van hierdie reg woon nou op die stapel. Ek het aan hulle gegee albei name. int star b is gelyk aan malloc grootte van int. Hierdie een mag wees 'n bietjie lastig. Neem 'n tweede en dink oor wat jy sou verwag om te gebeur op hierdie diagram. int star b is gelyk aan malloc grootte van int. Wel, dit is nie net 'n boks. Dit skep eintlik twee bokse. En dit bande, dit stel ook 'n punt in 'n verhouding. Ons het 'n blok toegeken geheue op die hoop. Let daarop dat die kassie regs bo daar nie 'n naam. Ons mallocd dit. Dit bestaan ​​op die hoop. Maar b het 'n naam. Dit is 'n wyser veranderlike genoem b. Wat leef op die stapel. So dit is 'n stuk van die geheue wat verwys na 'n ander een. b die adres bevat van daardie blok van die geheue. Dit maak nie 'n naam het anders. Maar dit wys om dit te. So wanneer ons sê int star b is gelyk aan malloc grootte van int dat net daar, dat pyl wat inloer op die regterkant daar dat die hele ding, Ek sal dit voorkom weer, is wat gebeur. Al wat gebeur in dat enkele lyn van die kode. Nou sal ons bietjie meer te kry eenvoudig weer. 'n gelyk ampersand m. Het jy onthou wat 'n gelyk ampersand m is? Wel, dit is 'n raak adres m se. Of sit meer diagrammaties 'n punte te m. 'n gelyk b. OK so hier is nog een. A is gelyk aan b. Wat gaan gebeur die diagram hierdie tyd? Wel onthou dat die opdrag operateur werke deur die toeken van die waarde van die reg om die waarde aan die linkerkant. So in plaas van 'n aanwysing te m, 'n nou wys na dieselfde plek wat b punte. 'n nie wys B, A wys waar b punte. As 'n skerp om B wat sou het reeds 'n gelyk ampersand b. Maar eerder 'n gelyk b net beteken dat en b is nou wys na dieselfde adres, omdat binnekant van b is net 'n adres. En nou binnekant van 'n is dieselfde adres. m gelyk aan 10, waarskynlik die mees eenvoudige ding ons gedoen het in 'n bietjie. Sit die 10 in die boks. Star b is gelyk aan m plus 2, onthou uit ons wenke video wat star b beteken. Ons gaan dereference b en sit 'n bietjie waarde in daardie geheue plek. In hierdie geval 12. So wanneer ons dereference 'n punt daarvan onthou ons het net reis af in die pyl. Of 'n ander manier, ons gaan na die geheue adres en ons manipuleer dit in een of ander manier. Ons het 'n bietjie waarde in daar. In hierdie geval ster b gelyk m plus 2 is net gaan na die veranderlike wys na die b, gaan na die geheue verwys na deur b, en sit m plus 2 daar, 12. Nou vry ek b. Wat gebeur wanneer ek vry b? Onthou wat ek gesê het vry beteken. Wat sê ek toe ek bevry b? Ek is klaar besig met dit, reg? Ek wese gee die geheue. Ek gee dit terug na die stelsel. Ek het nie nodig hierdie meer is wat ek vir hulle vertel, OK? Nou as ek sê star n gelyk 11 kan jy waarskynlik reeds vertel dat iets sleg gaan hier gebeur nie, reg? En inderdaad as ek probeer dat ek waarskynlik sou 'n segmentering skuld ly. Want nou, hoewel voorheen dat deel van die geheue was iets wat ek moes toegang tot, op hierdie punt nou is ek toegang tot geheue wat is nie reg vir my om toegang te kry. En soos ons sal waarskynlik onthou, wanneer ons toegang geheue dat ons nie veronderstel is om te raak, dit is die mees algemene oorsaak van 'n segmentering fout. En so my program sou crash as ek probeer om dit te doen. So weer dis 'n goeie idee om 'n goeie kry praktyk en goeie gewoontes ingeburgerde wanneer daar met malloc en vry, sodat jy nie ly segmentering foute, en wat jy gebruik jou dinamiese toegeken geheue verantwoordelik. Ek is Doug Lloyd dit is CS50.