[Muziek]
>> DOUG LLOYD: OK dus een suggestie voordat ik hier beginnen.
Als je de video op niet hebben bekeken pointers je zou willen dat eerst doen.
Omdat deze video is een ander manier van werken met pointers.
>> Dus het gaat om te praten over enkele concepten
dat we gaan in de pointers video, en we zijn
ga verdoezelen hen nu, in de veronderstelling dat ze al
soort van begreep.
Dus dat is gewoon je eerlijke waarschuwing dat als je ziet je deze video
en je hebt niet gezien de pointers video, is het misschien een soort van
vliegen over je hoofd een beetje.
En zo zou het beter zijn om hem te bekijken in die volgorde.
>> Dus we hebben al gezien een manier om te werken met pointers,
die verklaren wij een variabele, en dan hebben we
verklaart een andere variabele, een pointer variabele die verwijst naar het.
Dus we hebben gemaakt een variabele met een naam, we hebben
creëerde een tweede variabele met een naam, en wij wijzen dat tweede variabele
op die eerste.
Deze soort heeft een probleem, omdat het
moeten we precies weten hoeveel geheugen we
gaan naar het moment nodig ons programma is samengesteld.
>> Waarom is dat?
Want we moeten in staat zijn om een ​​naam of identificeren van alle mogelijke variabelen
we zouden kunnen tegenkomen.
We kunnen een array die mogelijk zijn in staat om veel informatie te houden,
maar het is nog steeds niet precies nauwkeurig genoeg.
Wat als we niet weten, wat als we hebben geen idee
hoeveel we nodig hebt tijdens het compileren?
Of wat als ons programma lopen voor een heel lange tijd,
aanvaarden van verschillende gebruikersgroepen data, en we kunnen niet echt
schatten of we zijn naar 1.000 eenheden moeten?
>> Het is niet alsof we kunnen zeggen op de opdrachtregel
voer hoeveel items je denkt dat je nodig hebt.
Nou wat als die gok is verkeerd?
Dynamische toewijzing van geheugen soort laat ons de weg
om rond dit specifieke probleem.
En de manier waarop het doet het is met behulp van pointers.
>> We kunnen pointers te gebruiken krijg toegang tot dynamisch
toegewezen geheugen, geheugen dat als je programma toegewezen wordt uitgevoerd.
Het is tijdens het compileren niet toegewezen.
Wanneer u dynamisch toewijzen geheugen het komt uit een pool
geheugen zogenaamde heap.
Eerder al het geheugen we hebben gewerkt met in de loop
is afkomstig van een pool geheugen zogenaamde stack.
Een goede manier om in het algemeen in mind-- en deze regel houden
niet altijd opgaat, maar vrij veel bijna
altijd geldt true-- is dat keer dat u een variabele naam geven
Waarschijnlijk woont op de stapel.
En elke keer dat je niet geven een variabele een naam,
die je kunt doen met dynamisch geheugen toewijzing, het leeft op de heap.
>> Nu ben ik soort presenteren dit als als er deze twee pools geheugen.
Maar u kunt dit hebt gezien diagram, die over het algemeen
een representatie van wat geheugen eruit ziet,
en we zijn niet van plan om over alle zorg het materiaal aan de bovenkant en de onderkant.
Wat we zorg over is dit deel in het midden hier, hoop en stack.
Zoals je kunt zien door bekijken dit diagram,
deze eigenlijk niet twee afzonderlijke pools van het geheugen.
Het is een gemeenschappelijk zwembad van het geheugen waar je begint, in deze visuele
je begint aan de onderkant en start vullen
vanaf de bodem van de stapel, en u beginnen bovenaan start opvullen
van boven naar beneden met de heap.
Maar het is echt de hetzelfde zwembad, het is gewoon
verschillende vlekken, verschillende locaties geheugen dat wordt toegewezen.
En je kunt uit te voeren geheugen door een van beide het hebben
de hoop de hele weg naar de bodem, of
de stapel gaan de hele weg naar de top, of het hebben van de hoop en de stapel
ontmoeten tegen elkaar.
Al deze voorwaarden kunnen worden dat je programma veroorzaken
uit het geheugen te lopen.
Dus hou dat in gedachten.
Wanneer we praten over de hoop en de stapel
we echt praten over het dezelfde algemene brok van geheugen,
verschillende delen van dat geheugen.
>> Dus hoe krijgen we dynamisch geheugen toegewezen in de eerste plaats?
Hoe werkt ons programma te krijgen geheugen als het draait?
Goed C bevat een functie genaamd malloc, geheugen allocator, die
u een gesprek te maken, en je passeert in hoeveel bytes van het geheugen dat u wilt.
Dus als je programma draait en u wilt een integer runtime,
je zou Mallock vier bytes geheugen, malloc haakjes vier.
>> Mallock zal gaan door kijken door de hoop,
omdat we dynamisch toewijzen van geheugen,
en het zal aan u terug een pointer naar dat geheugen.
Het geeft je niet dat memory-- het niet geef het een naam,
het geeft je een verwijzing naar het.
En dus dat is waarom weer zei ik dat het belangrijk is om misschien
de pointers video hebben bekeken voordat we te ver in dit.
Dus malloc gaat geef je terug een pointer.
>> Als Mallock u geen kunt geven geheugen omdat je uit hebt draaien,
het zal u terug een null pointer.
Weet je nog wat er gebeurt als we proberen en dereference een null pointer?
We lijden aan een seg fout, toch?
Dat is waarschijnlijk niet goed.
>> Dus elke keer dat u belt u altijd malloc, altijd
moet controleren of de pointer gaf je terug null.
Als het is, moet u uw programma te beëindigen want als je probeert en dereferentie
de null pointer je gaat een segmentation fault lijden
en uw programma is ga toch crashen.
Dus hoe kunnen we statisch krijgen een geheel getal?
>> int x.
We hebben waarschijnlijk gedaan een paar keer, toch?
Dit creëert een variabele genaamd x die leeft op de stapel.
Hoe kunnen we dynamisch een integer te krijgen?
Int ster px gelijk aan malloc 4.
>> Of meer naar behoren we zouden zeggen int ster px
gelijk aan malloc grootte van int, gewoon om wat minder te gooien
magische getallen rond ons programma.
Dit gaat te verkrijgen voor ons vier bytes van het geheugen van de hoop,
en de wijzer krijgen we terug naar het heet px.
En dan gewoon zoals we hebben eerder gedaan wij
kan dereferentie px aan toegang tot die herinnering.
Hoe krijgen we een geheel getal van de gebruiker?
We kunnen zeggen int x gelijk krijgen int.
Dat is vrij eenvoudig.
Wat als we willen een array x van praalwagens die leven op de stapel?
zweven stack_array-- dat is de naam van onze array-- vierkante haken x.
Dat zal creëren voor ons een array x van praalwagens die leven op de stapel.
We kunnen een scala van praalwagens creëren die leeft op de hoop, ook.
De syntaxis ziet er misschien een beetje meer omslachtig,
maar we kunnen zeggen float ster heap_array gelijk
malloc x keer de grootte van de vlotter.
Ik moet genoeg ruimte om vast te houden x floating point waarden.
Dus zeg ik moet 100 drijvers, of 1000 praalwagens.
Dus in dat geval zou zijn 400 bytes 100 drijvers,
of 4000 bytes 1000 floats, omdat elke vlotter neemt
vier bytes van de ruimte.
>> Na dit te doen kan ik gebruik maken van de square bracket syntax op heap_array.
Net zoals ik zou doen op stack_array, I kunnen de elementen individueel toegang
gebruik heap_array nul heap_array één.
Maar herinneren aan de reden kunnen we dat doen is omdat de naam van een array in C
is echt een verwijzing naar van die array eerste element.
Dus het feit dat we verklaren een scala van praalwagens op de stapel hier
is eigenlijk een beetje misleidend.
We zijn echt in de tweede regel code er
Ook het creëren van een verwijzing naar een stuk van geheugen dat we nog wat werk aan te doen.
>> Hier is het grote probleem met dynamisch toegewezen geheugen hoewel,
en dit is waarom het is echt het belangrijk om een ​​aantal goede gewoonten te ontwikkelen
wanneer u werkt met het.
In tegenstelling tot statisch verklaard geheugen, uw geheugen
niet automatisch terugkeren naar de systeem wanneer uw functie wordt gedaan.
Dus als we de belangrijkste, en belangrijkste noemt een functie
f, wanneer f afwerking wat het doet en geeft de controle van het programma
terug naar de belangrijkste, al het geheugen dat f gebruikt wordt terug gegeven.
Het kan weer worden gebruikt door een ander programma,
of een andere functie die wordt aangeroepen later op in de belangrijkste.
Het kan dat hetzelfde geheugen opnieuw gebruiken voorbij.
>> Als u dynamisch geheugen toewijzen al
moet u expliciet zeggen de systeem dat je klaar bent met het.
Het zal vast te houden voor u, die kan leiden tot een probleem van je opraken
geheugen.
En in feite we soms verwijzen om dit als een geheugenlek.
En soms zijn deze geheugenlekken eigenlijk kan echt verwoestende
voor de systeemprestaties.
>> Als u een frequente gebruiker van internet je zou het gebruik van bepaalde webbrowsers,
en ik zal hier niet de namen noemen, maar er zijn een aantal webbrowsers die er zijn
die berucht voor het daadwerkelijk te hebben zijn geheugenlekken die niet opgelost.
En als u uw browser geopend voor een zeer lange tijd, dag
en dagen of weken, je soms misschien merken dat uw systeem
is het uitvoeren van heel, heel langzaam.
De reden daarvoor is dat de browser heeft geheugen toegewezen,
maar dan niet het systeem te horen dat het is gedaan met het.
En zo dat minder geheugen verlaat beschikbaar voor al uw andere programma's
te hebben om te delen, omdat je leaking-- dat webbrowser
programma lekt geheugen.
Hoe geven we het geheugen terug als we klaar zijn met het?
Nou gelukkig is het een zeer eenvoudige manier om het te doen.
We bevrijden het gewoon.
Er is een gratis functie genaamd, het een pointer accepteert naar het geheugen,
en we zijn goed om te gaan.
>> Dus laten we zeggen dat we in de midden van ons programma,
we willen 50 tekens malloc.
We willen een array die kunnen malloc staat van het bedrijf 50 tekens.
En als we een pointer terug naar dat de naam van die wijzer woord.
We doen wat we zijn gaan doen met woord,
en toen we doen we vrij het gewoon.
En nu hebben we terug die 50 bytes geheugen naar het systeem.
Enkele andere functie kunt gebruiken.
We hebben geen zorgen te maken over het lijden van een geheugenlek omdat we hebben woord bevrijd.
We hebben het geheugen teruggegeven, dus we zijn klaar ermee werken.
Er zijn dus drie gouden regels die moeten
in het achterhoofd worden gehouden wanneer u bent dynamisch toewijzen van geheugen
met malloc.
Elk blok van het geheugen dat je moet malloc worden bevrijd
voordat het programma klaar is uitgevoerd.
Nu weer in het toestel of in de IDE dit soort gebeurt je toch
wanneer u-- dit toch zal gebeuren wanneer het programma wordt beëindigd,
al het geheugen zal worden vrijgegeven.
Maar het is over het algemeen goed codering gewoonte om altijd, als je klaar bent,
bevrijden wat je hebt mallocd.
>> Dat gezegd hebbende, enige dingen die je hebt mallocd moet worden bevrijd.
Als u statisch verklaart een integer, int x puntkomma,
die leeft op de stapel, u niet dan willen bevrijden x.
Dus alleen de dingen die je hebt mallocd moeten worden bevrijd.
>> En tot slot, niet vrij iets tweemaal.
Dat kan leiden tot andere rare situatie.
Dus alles wat je hebt mallocd moet worden bevrijd.
Enige dingen die je hebt malloc moeten worden bevrijd.
En doe niet vrij iets tweemaal.
>> Dus laten we gaan door middel van een voorbeeld hier van wat sommige dynamisch toegewezen
geheugen eruit zou kunnen zien gemengde in enkele statisch geheugen.
Wat kan hier gebeuren?
Kijk of je kunt volgen langs en wat denk je is
gaat gebeuren als we gaan door al deze regels code.
>> Dus zeggen wij int m.
Wat gebeurt hier?
Nou, dit is vrij eenvoudig.
Ik maak een integer variabele genaamd m.
Ik kleur het groen, want dat is de kleur
die ik gebruik als ik praat over integer variabelen.
Het is een doos.
Het heet m, en u kunt integers winkel binnen van het.
>> Wat als ik dan zeggen int een ster?
Nou dat is redelijk vergelijkbaar.
Ik ben het creëren van een doos genoemd.
Het is in staat van het bedrijf int sterren, verwijzingen naar gehele getallen.
Dus ik ben te kleuren groen-ish ook.
>> Ik weet dat het iets te maken met een integer,
maar het is niet zelf een integer.
Maar het is vrijwel hetzelfde idee.
Ik heb een doos gemaakt.
Beide recht wonen nu op de stapel.
Ik heb ze gezien beide namen.
>> int ster b gelijk aan malloc grootte van int.
Dit misschien een beetje lastig.
Neem een ​​tweede en nadenken over wat je zou verwachten dat er gebeurt op dit diagram.
int ster b gelijk aan malloc grootte van int.
>> Nou, dit is niet alleen te maken een doos.
Dit creëert in feite twee dozen.
En het stropdassen, maar stelt ook een punt in een relatie.
We hebben een blok toegewezen geheugen in de heap.
Merk op dat de rechter box er heeft geen naam.
>> We mallocd het.
Deze zich op de heap.
Maar b heeft een naam.
Het is een pointer variabele genaamd b.
Die woont op de stapel.
>> Dus het is een stuk van het geheugen die verwijst naar een andere.
b bevat het adres van dat geheugenblok.
Het heeft geen naam anders.
Maar het wijst op het.
Dus als we zeggen int ster b gelijk malloc grootte van int, dat daar,
dat de pijl die dook op de rechterkant is er, dat de hele zaak,
Ik zal het lijken weer, is wat er gebeurt.
Dat alles gebeurt in dat enkele regel code.
Nu zullen we weinig meer te halen ongecompliceerd weer.
een gelijk ampersand m.
Herinnert u zich wat een evenaart ampersand m is?
Nou dat is een krijgt adres m's.
Of zet meer schematisch een punten meter.
>> a is gelijk aan b.
OK dus hier is een andere.
A gelijk is aan b.
Wat gaat er gebeuren het schema ditmaal?
>> Goed herinneren dat de toewijzingsoperator werken
door aan de waarde op de recht op de waarde links.
Dus in plaats van te wijzen op m, een nu wijst op dezelfde plaats die b punten.
een niet wijzen op B, A wijst waarbij b punten.
>> Als een puntig naar b, dat zou hebben een gelijk ampersand b.
Maar in plaats daarvan een gelijk b net betekent dat en b nu
wijzend naar hetzelfde adres, omdat binnenkant van b is slechts een adres.
Nu binnenkant van hetzelfde adres.
m gelijk is aan 10, waarschijnlijk meest eenvoudige ding
we hebben gedaan in een klein beetje.
Zet de 10 in de doos.
Star b gelijk aan m plus 2, herinnert uit onze pointers video wat ster b betekent.
We gaan dereferentie b en put enige waarde in dat het geheugen locatie.
In dit geval 12.
>> Dus toen we dereference een punt van herinneren we reizen naar beneden de pijl.
Of anders gezegd, we naar die geheugenadres
en we manipuleren op een bepaalde manier.
We zetten enkele waarde in.
In dit geval ster b evenaart m plus 2 is gewoon
naar de variabele gewezen door b, naar het geheugen wordt gewezen door b,
en zet m plus 2 daar, 12.
>> Nu vrij ik b.
Wat gebeurt er als ik vrij B?
Vergeet niet wat ik zei vrije middelen.
Wat zeg ik als ik vrij B?
>> Ik ben klaar met werken, toch?
Ik wezen geven het geheugen.
Ik geef het terug naar het systeem.
Ik hoef niet dit niet meer is wat ik te vertellen, oké?
>> Nu als ik zeg een ster gelijk aan 11 kunt u waarschijnlijk
al zeggen dat er iets ergs gaat hier gebeuren, toch?
En inderdaad, als ik probeerde dat ik waarschijnlijk zou een segmentation fault lijden.
Omdat nu, hoewel eerder dat stuk van het geheugen
was iets dat ik had toegang tot op dit punt
nu ben ik de toegang tot het geheugen dat is niet legaal voor mij om toegang te krijgen.
>> En zoals we zullen waarschijnlijk herinneren, wanneer we toegang tot het geheugen
dat we niet verondersteld te raken, dat is de meest voorkomende oorzaak
van een segmentatie fout. En dus mijn programma
zou crashen als ik probeerde om dit te doen.
Dus nogmaals, het is een goed idee om goed te krijgen praktijk en goede gewoonten ingesleten
bij het werken met malloc en gratis, zodat u geen last heeft segmentatie
fouten, en dat je gebruikt je dynamisch toegewezen
geheugen op verantwoorde wijze.
>> Ik ben Doug Lloyd is CS50.