[За възпроизвеждане на музика] Дъг LLOYD: ОК, така предложение преди да започне тук. Ако не сте гледали видеото Указатели може да искате да го направите първата. Поради това видео е друг начин на работа с указатели. Така, че ще ходи да говори за някои концепции които ние покриваме в Указатели на видео, и ние сме ще замаже тях сега, ако се приеме, че те вече са нещо като разбра. Така че това е само справедлива предупреждение че ако вие виждате това видео а не сте виждали указатели видео, той може нещо летят над главата си малко. И така, тя може да бъде по-добре да го гледате в този ред. Така че ние вече видяхме една начин да се работи с указатели, което е ние да обяви променлива, и тогава ние Декларирам друга променлива, указател променлива, която сочи към нея. Така че ние създадохме променлива с име, ние сме създаде втората променлива с име, и ние се отбележи, че втората променлива на първата. Този вид има проблем обаче, тъй като тя изисква от нас да се знае точно колко памет сме ще се нуждаем в момента нашата програма е съставена. Защо така? Защото ние трябва да можем да назовем или идентифицират всички възможни променливи ние може да срещнете. Ние може да има масив, който може да бъде в състояние да държи много информация, но тя все още не е точно достатъчно прецизни. Какво става, ако ние не знаем, какво, ако ние нямаме представа колко ще ни трябва по време на компилация? Или какво, ако нашата програма ще кандидатира за много дълго време, приемайки различни потребителя данни, и ние не можем наистина изчислите дали сме ще се нуждаят от 1000 единици? Това не е като можем казват в командния ред въведете колко елемента мислите, че ще се наложи. Ами какво, ако това предположение не е наред? Dynamic разпределение на паметта нещо като ни позволява пътя да се получи около този конкретен проблем. И начина, по който го прави е чрез използване на указатели. Ние можем да използваме указатели към получите достъп до динамично разпределена памет, памет, разпределени както вашата програма се изпълнява. Това не е разпределен по време на компилация. Когато динамично разпределя памет идва от басейн памет известен като купчината. Преди всичко, ние сме на паметта работи с в хода е, идващи от басейн памет известен като комин. Един добър начин за цяло имайте mind-- и това правило не винаги важи, но доста много почти винаги държи true-- е, че всяко Време ви даде името на променливата я вероятно живее в стека. И всеки път, когато не го правят даде променлива име, които можете да правите с динамична памет разпределение, тя живее на куп. Сега съм вид представяне на това като ако има тези два басейна на паметта. Но може би сте виждали това диаграма, която обикновено представяне на това, което изглежда като памет, и ние няма да се грижи за всички нещата в горната и долната част. Какво ни интересува, е тази част от средата тук, купчината и топчето. Както можете да видите от погледнете в тази схема, те всъщност не са две отделни басейна на паметта. Това е един общ басейн на паметта къде да започнете, в тази визуална да започнете на дъното и да започне попълване от дъното с комина, и вие започнете от върха и да започне попълване от горе на долу с куп. Но това наистина е най- същия басейн, това е просто различни места, различни места в паметта, които са били отпуснати. И вие може да се изчерпи памет от която и като купчината отидем по целия път към дъното, или имат стека отидем по целия път до върха, или като на куп и топчето срещнат един срещу друг. Всички тези условия може да бъде които предизвикват вашата програма до изчерпване на паметта. Така че имайте това предвид. Когато говорим за купчината и топчето ние наистина говорим за същата обща парче от паметта, просто различни части на тази памет. Е, как да стигнем динамично разпределена памет на първо място? Как да получите нашата програма памет, както той се движи? Е C осигурява функция, наречена изчистване, памет разпределител, който можете да осъществите повикване до, и да премине в колко байта памет, които искате. Така че, ако вашата програма се изпълнява и искате цяло число по време на работа, може Малок четири байта памет, изчистване скоби четири. Малок ще мине през гледам през купчината, защото ние сме динамично разпределяне на паметта, и то ще се върне при вас указател към тази памет. Това не ви дава, че memory-- тя не му се даде име, той ви дава указател към него. И така, ето защо отново казах че е важно да може Гледал видеото на указатели преди да стигнем твърде далеч в това. Така изчистване ще ти върна указател. Ако Малок не може да ви даде всеки памет, защото е свършило, тя ще ви върне нулев указател. Спомняте ли си какво ще стане, ако ние опитайте и сочен нулев указател? Ние страдаме вина на сегменти, нали? Това вероятно не е добра. Така че всеки път, когато направите повикване да ви изчистване винаги, винаги Трябва да се провери дали или не показалеца ви го даде обратно е нищожна. Ако е така, трябва да се сложи край на програма защото, ако се опитате и сочен нулевата показалеца ти започваш имаше вина сегментация и програмата ви е ще се разбие, така или иначе. Е, как да направим статично получи число? инт х. Ние вероятно сме направили, че куп пъти, нали? Това създава променлива х, който живее в стека. Как можем динамично получи цяло число? Int звезда пиксела равнява изчистване 4. Или по-подходящо щяхме да кажем инт звезда пиксела се равнява на изчистване размер на вътр, само за да хвърли малко по-малко магически числа около нашата програма. Това ще се получи за нас четири байта памет от купчината, и показалеца стигнем обратно към това се нарича пиксела. И тогава, точно както ние сме направено преди това ние може да сочен пиксела достъп до тази памет. Как да стигнем до цяло число от потребителя? Можем да кажем, инт х равнява получите инт. Това е доста ясен. Какво става, ако искаме да се създаде масив на х плувки, които живеят в стека? плаваш stack_array-- това е името от нашите array-- квадратни скоби х. Това ще създаде за нас масив на х плувки, които живеят в стека. Ние можем да създадем масив от поплавъци който живее на куп, също. Синтаксисът може да изглежда малко по-тромава, но можем да кажем плувка звезден heap_array равнява изчистване х пъти размера на плувката. Имам нужда от достатъчно място за провеждане х стойности с плаваща запетая. Така че да кажа, че се нуждаят 100 плувки, или 1000 поплавъци. Така че в този случай би било 400 байта за 100 плувки, или 4000 байта за 1000 поплавъци, защото всеки поплавък заема четири байта пространство. След този начин мога да използвам квадратни скоби на heap_array. Точно както аз бих върху stack_array, I да получите достъп до неговите елементи поотделно използвайки heap_array нула, heap_array един. Но припомни причината можем да направим това е така, защото името на масив в C наистина е указател към Първият елемент, който е масив. Така че фактът, че ние сме обявяване на масив от поплавъци на стека тук всъщност е малко подвеждащо. Ние наистина сме в втори ред код там Също така се създава указател към парче памет, която ние след това се направят някои работи с. Тук е големият проблем с динамично разпределена памет все пак, и това е причината, че е наистина важно да се развият някои добри навици когато работите с него. За разлика от статично декларирани памет, паметта си не се връща автоматично към система, когато си функция е направено. Така че, ако ние имаме основна и Основната призовава функция е, когато е завършен каквото и да прави, и връща контрол на програмата обратно към основната, цялата памет че е използван, е върната. Тя може да се използва отново от някоя друга програма, или някаква друга функция, получава наречена по-късно в основната. Тя може да се използва същата памет отново. Ако динамично достатъчно памет макар вие трябва да кажете на изрично система, която сте готови с нея. Тя ще се задържи на него за вас, които биха могли да доведе до проблем от вас изчерпване памет. И всъщност ние понякога се отнасят към това, както теч с памет. И понякога тези течове памет всъщност може да бъде наистина унищожително за работата на системата. Ако сте често интернет потребител можете да използвате някои уеб браузъри, и аз няма да назове имена тук, но има някои уеб браузъри там които са известни за да се налага изтичане на памет, които не се оправят. И ако оставите вашия браузър с отворен за един много дълъг период от време, дни и дни или седмици, понякога Може да забележите, че вашата система Течаща наистина, наистина бавно. И причината за това е, че браузърът е отделил паметта, но тогава не каза системата че това е направено с него. И така, който оставя по-малко памет достъпно за всички други вашите програми да има да сподели, защото сте leaking-- че уеб браузър програма изтича памет. Как да даваме памет обратно когато сме готови с него? Ами за щастие това е много лесен начин да го направя. Ние просто го освободи. Има една функция, наречена безплатно, тя приема указател към паметта, и ние сме добре да тръгвам. Така че нека да кажем, че сме в средата на нашата програма, ние искаме да изчистване 50 знака. Искаме да изчистване масив, който може да може да задържа 50 знака. И когато ние получим указател обратно че, име, което показалеца е дума. Ние правим каквото сме ще правите с дума, и след това, когато сме направено, ние просто го освободи. И сега ние се върнат тези 50 байта памет обратно в системата. Някои други функции може да ги използва. Ние не трябва да се притеснявате за страданието памет течове, защото ние сме освободени дума. Дадохме паметта обратно, така че ние сме готови да работи с него. Така че те са три златни правила, които трябва да да се има предвид, когато сте динамично разпределяне на паметта с изчистване. Всеки блок от паметта, която можете изчистване трябва да се освободи преди вашата програма завършва работи. Сега отново, в уреда или в IDE този вид се случва така или иначе когато you-- това ще се случи така или иначе когато вашата програма се прекратява, всички паметта ще бъде освободен. Но това е като цяло добро кодиране практика винаги, когато сте готови, освободим това, което сте mallocd. Това каза, само неща, които сте mallocd трябва да бъде освободен. Ако статично обявят число, инт х точка и запетая, който живее в стека, вие не след това искаме да освободим х. Така че само неща, които сте mallocd трябва да бъде освободен. И накрая, не го правят безплатно нещо два пъти. Това може да доведе до друга странна ситуация. Така че всичко, което сте mallocd трябва да бъде освободен. Само неща, които сте изчистване трябва да бъде освободен. И не го правят безплатно нещо два пъти. Така че нека да мине през един пример тук на това, което някои динамично разпределена памет може да изглежда като смесена в с някои статична памет. Какво може да се случи тук? Виж, ако можете да следвате заедно и предполагам, че това, което е ще се случи като отидем през всичките тези редове код. Така че ние казваме инт m. Какво се случва тук? Ами това е доста ясен. Създавам целочислена променлива, наречена m. I оцветите го направи зелен, защото това е цветът която използвам, когато аз говоря около целочислени променливи. Това е кутия. Тя се нарича м, и можете да магазин числа вътре в него. Какво става, ако след това казват инт звезда? Ами това е доста сходен. Аз съм създаване кутия нарича. Това е в състояние да задържа инт звезди, указатели към цели числа. Така че аз съм го оцветяване зелено-Иш, както добре. Знам, че има нещо общо с цяло число, но това не се е цяло число. Но това е почти една и съща идея. Аз създадох една кутия. И двете неща полето сега живея в стека. Аз съм ги дал и двете имена. инт звезда б равнява изчистване размер на инт. Този човек може да бъде малко трудно. Вземете една секунда и да мисля за това, което ще очаквам да се случи на тази схема. инт звезда б равнява изчистване размер на инт. Ами това не просто да се създаде една кутия. Това всъщност създава две кутии. И това връзва, тя също така създава точка в една връзка. Ние сме разпределени един блок на паметта на куп. Забележете, че в горния десен прозорец там все още няма име. Ние го mallocd. Тя съществува на куп. Но б има име. Това е променлива указател нарича б. Това живее в стека. Така че това е парче от паметта който сочи към друг. б съдържа адреса на този блок на паметта. Тя не разполага с името на друго мнение. Но той насочва към него. Така че, когато казваме, инт звезда б равнява Размер на изчистване на инт, че точно там, че стрелка, която показа на на дясна страна там, че цялата работа, Ще трябва да изглежда отново, е това, което се случва. Всичко, което се случва в че един ред код. Сега ние ще се заемем малко повече лесно отново. а равнява амперсанд m. Спомняте ли си какво е равнява амперсанд m е? Ами това е един получава адрес м е. Или казано по-схематично, на точки до м. равнява на б. OK така че ето още един. А е равно б. Какво ще се случи диаграмата този път? Ами Спомнете си, че оператор за присвояване произведения чрез възлагане на стойността, на право на стойността в ляво. Така че, вместо да посочващо m, а сега точки на същото място, че В точки. а не насочва към B, A изтъква, където б точки. Ако заострен да б, които биха да е равнява амперсанд б. Но вместо това се равнява само на б означава, че и сега са б сочейки към същия адрес, защото вътре в б е само един адрес. И сега във вътрешността на е на същия адрес. m е равно на 10, може би най- Най-простият нещо ние сме направили в малко. Поставете 10 в наказателното поле. Star б равнява m плюс 2, припомнят от нашата указатели видео каква звезда б означава. Отиваме да сочен б и пут някаква ценност в това място в паметта. В този случай 12. Така че, когато ние сочен точка на припомним ние просто пътуват надолу стрелката. Или казано по друг начин, ние отидете на този адрес памет и ние го манипулират по някакъв начин. Ние събрахме някои стойност там. В този случай те б равнява m плюс 2 е просто отидете на променливата, посочи от б, отидете на паметта, посочи от б, и сложи м плюс 2 там, 12. Сега освободи б. Какво се случва, когато се освободи б? Спомни си какво казах свободни средства. Какви ги говоря, когато освободите б? Свърша работата с него, нали? Аз по същество да се откаже от паметта. Аз го върне към системата. Нямам нужда от това повече е това, което аз им казвам, OK? Сега, ако кажа звезда се равнява на 11 вероятно можете да вече кажа, че нещо лошо ще се случи тук, нали? И наистина, ако аз се опитах, че вероятно ще претърпи повреда сегментация. Защото сега, въпреки че преди това, че парче от паметта е нещо, което аз трябваше достъп до тях, в този момент сега съм достъп до паметта, която не е правен за мен да осъществите достъп. И тъй като ние вероятно ще спомняте, когато достъп до паметта че ние не би трябвало да се докоснат, това е най-честата причина на сегментацията Аномалия. И така, моята програма щеше да се блъсне, ако аз се опитах да направя това. Така че отново, че е добра идея да се получи добър практики и добри навици вкоренен при работа с изчистване и безплатно, така че да не страдат сегментацията неизправности, и които се използват Вашата динамично разпределена памет отговорно. Аз съм Дъг Lloyd това е CS50.