[Гуляе музыка] Даг Lloyd: Добра, такім чынам прапанову перад пачаткам тут. Калі вы не глядзелі відэа на паказальнікі вы можаце зрабіць так у першую чаргу. Таму што гэта відэа з'яўляецца яшчэ адным спосаб працы з паказальнікамі. Такім чынам, гэта будзе казаць аб некаторых паняццяў што мы разгледзім у Паказальнікі відэа, і мы збіраецца замоўчваць іх цяпер, мяркуючы, што яны ўжо накшталт зразумеў. Так што гэта проста ваш справядлівае папярэджанне што калі вы бачыце гэта відэа і вы яшчэ не бачылі паказальнікі відэа, гэта магло б свайго роду лётаць над вашай галавой няшмат. І так было б лепш каб паглядзець яго ў такім парадку. Такім чынам, мы ўжо бачылі адзін спосаб працы з паказальнікамі, што мы аб'явіць Пераменная, а затым мы абвясціць яшчэ адну зменную, паказальнік Пераменная, якая паказвае на яго. Такім чынам, мы стварылі Пераменная з імем, мы стварыў другую зменную з імем, і мы паказваем, што другая пераменная на што ў першую чаргу. Гэты выгляд мае Праблема, хоць, таму што гэта патрабуе ад нас, каб дакладна ведаць, колькі памяці мы спатрэбіцца ў той момант, наша праграма будзе скампіляваць. Чаму так? Таму што мы павінны быць у стане назваць або вызначыць усе магчымыя пераменныя мы маглі б сутыкнуцца. Мы маглі б мець масіў, што можа быць ў стане трымаць шмат інфармацыі, але гэта яшчэ не дакладна досыць дакладным. Што рабіць, калі мы не ведаем, што, калі ў нас няма ні найменшага падання колькі нам трэба падчас кампіляцыі? Ці што, калі наша праграма будзе запусціць на працягу сапраўды доўгага часу, прымаючы розныя карыстальніка дадзеных і мы не можам на самай справе ацаніць Ці мы спатрэбіцца 1000 адзінак? Гэта не тое, мы можам кажуць у камандным радку увядзіце колькі прадметаў Вы думаеце, што вы будзеце мець патрэбу. Ну што, калі гэта здагадка няслушна? Дынамічнае вылучэнне памяці роду дазваляе нам шлях каб абыйсці гэтай канкрэтнай праблемы. І тое, як ён гэта робіць з'яўляецца выкарыстанне паказальнікаў. Мы можам выкарыстоўваць паказальнікі на атрымаць доступ да дынамічна выдзеленая памяць, памяць, выдзелена ў якасці праграмы. Гэта не вылучаецца падчас кампіляцыі. Калі вы дынамічна вылучаць памяці яна зыходзіць ад басейна памяці вядомы як кучы. Раней усе мы ў памяці працуе з у ходзе быў зыходзячы з пула памяці вядомы як стэк. Добры спосаб, як правіла трымаць у mind-- і з гэтага правіла не заўсёды справядлівыя, але ў значнай ступені амаль заўсёды трымае true--, што любы раз вы даць імя зменнай яго верагодна, жыве ў стэку. І ў любы час вы не даць зменнай імя, якія вы можаце зрабіць з дынамічнай памяццю размеркаванне, яна жыве ў кучы. Цяпер я накшталт прадстаўлення, як гэта калі ёсць гэтыя два басейна памяці. Але вы, магчыма, бачылі гэта Дыяграма, якая, як правіла прадстаўленне тое, што памяць выглядае, і мы не збіраемся, каб клапаціцца пра ўсё матэрыял у верхняй і ніжняй часткі. Тое, што мы клапоцімся пра тое, гэтая частка ў сярэдні тут, куча і стэк. Як вы можаце бачыць, гледзячы на ​​гэтую дыяграму, гэта на самай справе не два асобныя басейны памяці. Гэта адна агульная пул памяці дзе вы пачынаеце ў гэта візуальная Вы пачынаеце ў ніжняй і пачаць запаўненне са дна стэка, і вы пачаць у верхняй і пачаць запаўненне зверху ўніз з кучы. Але на самой справе гэта той жа пул, гэта проста розныя плямы, розных месцах у памяці, якія вылучаюцца. І вы можаце працаваць з памяці, альбо якія маюць куча прайсці ўвесь шлях на дно, або стэк прайсці ўвесь шлях да вяршыні, або якія маюць кучу і стэк сустрэцца адзін з адным. Усе тыя, можа быць ўмовы якія выклікаюць вашу праграму бегчы з памяці. Так што майце гэта на ўвазе. Калі мы гаворым пра куча і стэк мы на самай справе гаворым пра Наогул жа кавалак памяці, проста розныя часткі гэтай памяці. Так як жа нам атрымаць дынамічна размеркаванай памяці ў першую чаргу? Як атрымаць нашу праграму памяці, як ён працуе? Ну З прадугледжана функцыя Таноса, памяць размеркавальнік, які Вы робіце выклік, і вы праходзіце ў колькі байт памяці, якія вы хочаце. Так што, калі ваша праграма працуе і вы хочаце цэлае выканання, Вы маглі б Mallock чатыры байта памяці, Таноса дужкі чатыры. Mallock будзе прайсці гледзячы праз кучу, таму што мы дынамічна выдзялення памяці, і ён вернецца да вас паказальнік на гэтую памяць. Гэта не дае вам, што memory-- гэта не дае яму імя, гэта дае вам паказальнік на яго. І вось чаму я зноў сказаў што важна, можа быць, прагледзелі відэа паказальнікі перш чым мы атрымаем занадта далёка ў гэтым. Так Таноса збіраецца даць вам назад паказальнік. Калі Mallock не магу даць вам якой-небудзь памяці, таму што вы запусціце з, гэта дасць Вам нулявы паказальнік. Вы памятаеце, што адбудзецца, калі мы паспрабаваць разнаймення нулявога паказальніка? Мы пакутуем няспраўнасць SEG, ці не так? Гэта, верагодна, не вельмі добра. Такім чынам, кожны раз, калі вы зрабіць званок каб Таноса вас заўсёды, заўсёды неабходна праверыць, ці з'яўляецца паказальнік ён даў вам назад пустым. Калі гэта так, вы павінны скончыць вашу праграму таму што, калі вы паспрабуеце і разнаймення нулявы паказальнік вы збіраецеся пакутаваць памылку сегментацыі і ваша праграма ўрэжацца ў любым выпадку. Так, як мы статычна атрымаць цэлы лік? INT х. Мы, верагодна, зрабілі што кучу раз, праўда? Гэта стварае зменную з імем х, які жыве ў стэку. Як мы дынамічна атрымліваем лік? Int зорка ПВ роўная Таноса 4. Або больш дарэчы мы б сказалі, INT зорак кропак роўная выдзялення памяці памер Int, проста кінуць некаторыя менш магічныя колькасці вакол нашай праграмы. Гэта будзе для нас атрымаць чатыры байта памяці з кучы, і паказальнік мы атрымліваем вярнуцца да яе называецца пікс. А потым проста, як мы зроблена раней мы можа разыменовать пікселяў на доступ да гэтай памяці. Як мы можам атрымаць цэлы лік ад карыстальніка? Мы можам сказаць, INT х роўны атрымаць Int. Гэта даволі проста. Што рабіць, калі мы хочам стварыць масіў х паплаўкоў, якія жывуць у стэку? плаваць stack_array-- гэтае імя нашых array-- квадратных дужках х. Гэта створыць для нас масіў х паплаўкоў, якія жывуць у стэку. Мы можам стварыць масіў паплаўкоў што жыве ў кучы, таксама. Сінтаксіс можа выглядаць трохі больш грувасткім, але мы можам сказаць, паплавок зоркавы heap_array роўная Таноса х разоў памер паплаўка. Мне трэба досыць месцы, каб правесці х з якая плавае коскі. Так бы мовіць, мне трэба 100 паплаўкі, або 1000 паплаўкі. Так што ў гэтым выпадку было б 400 байт на 100 паплаўкоў, ці 4000 байт на 1000 паплаўкоў, таму што кожны паплавок займае чатыры байта прасторы. Пасля гэтага я магу выкарыстоўваць квадрат сінтаксіс кранштэйн heap_array. Гэтак жа, як я б на stack_array, я можа атрымаць доступ да яго элементы паасобку выкарыстоўваючы heap_array нуля, heap_array адным. Але ўспомніць прычыну мы можам зрабіць, што гэта таму, што імя масіва ў C сапраўды паказальнік на Першы элемент гэтага масіва. Так на тое, што мы аб'яўленні масіў плавае ў стэку тут на самай справе трохі ўводзіць у зман. Мы сапраўды ў Другая радок кода ёсць Таксама стварэнне паказальнік на кавалак памяці, што мы тады рабіць нейкую працу з. Вось вялікая праблема з дынамічнай памяццю, хоць, і менавіта таму гэта сапраўды Важна распрацаваць некаторыя добрыя звычкі калі вы працуеце з ім. У адрозненне ад статычна аб'яўлена памяці, ваша памяць аўтаматычна не вяртаецца ў Сістэма, калі ваша функцыя зрабіць. Так што, калі ў нас ёсць галоўны, і Асноўны выклікае функцыю е, калі F аздаблення ўсё, што робіць і вяртае кіраванне праграмай на галоўную, уся памяць што F выкарыстоўваецца даецца таму. Ён можа быць выкарыстаны зноў іншай праграмай, ці некаторыя іншыя функцыі, якія выклікаецца пазней у асноўным. Ён можа выкарыстоўваць гэтую ж памяць зноў і зноў. Калі вы дынамічна вылучыць памяць, хоць Вы павінны відавочна паказаць Сістэма, што вы зрабілі з ім. Гэта будзе трымаць на яго для вас, якія маглі б прывесці да праблемы з вас сыходзіць памяці. І на самай справе, мы часам называем на гэта як ўцечка памяці. І часам гэтыя ўцечкі памяці можа на самай справе быць сапраўды разбуральным для прадукцыйнасці сістэмы. Калі вы часта інтэрнэт-карыстальнік Вы маглі б выкарыстоўваць некаторыя вэб-браўзэры, і я не буду называць імёнаў тут, але Ёсць некаторыя вэб-браўзэры там што сумна вядомыя фактычна не маючы уцечкі памяці, якія не атрымліваюць фіксаваныя. І калі вы выходзіце ваш браўзэр з адкрытым для вельмі доўгага перыяду часу, дзён і дзён, ці тыдняў, часам Можна заўважыць, што ў вашай сістэме гэта працуе насамрэч, вельмі павольна. І прычына для гэтага з'яўляецца тое, што браўзэр вылучыў памяць, але тады не паведаміў сістэму што гэта зроблена з ім. І так, што пакідае менш памяці даступныя для ўсіх вашых іншых праграм каб падзяліцца, таму што вы leaking-- што вэб-браўзэр Праграма ўцечка памяці. Як мы даем памяць назад калі мы зрабілі з ім? Ну, на шчасце, гэта вельмі просты спосаб зрабіць гэта. Мы проста вызваліць яго. Там гэта функцыя называецца свабодным, ён прымае паказальнік на памяць, і мы добра ісці. Такім чынам, давайце казаць, што мы ў сярэдзіна нашай праграмы, мы хочам, каб Таноса 50 знакаў. Мы хочам, каб Таноса масіў, які можа здольная ўтрымліваць 50 знакаў. І калі мы атрымліваем паказальнік назад што імя гэтага паказальніка з'яўляецца слова. Мы робім усё, што мы збіраецца рабіць са словам, а затым, калі мы зроблена, мы проста вызваліць яго. А зараз мы вярнуліся тыя 50 байт памяці назад у сістэму. Некаторыя іншыя функцыі могуць іх выкарыстоўваць. Мы не павінны турбавацца аб пераносячы ўцечка памяці, таму што мы вызвалілі слова. Мы далі памяць назад, так, што мы скончылі працаваць з ім. Такім чынам, ёсць тры Залатыя правілы, якія павінны мець на ўвазе, калі вы дынамічнага размеркавання памяці з Таноса. Кожны блок памяці, Вы Таноса павінны быць вызваленыя Перад вашай праграмы завяршэння працы. Цяпер зноў, ў прыладзе або ў IDE такога роду адбываецца для вас у любым выпадку калі you-- гэта адбудзецца ў любым выпадку калі ваша праграма завяршаецца, уся памяць будзе выпушчаны. Але гэта ў цэлым добры кадаваньне Практыка заўсёды, калі вы скончыце, вызваліць тое, што вы mallocd. Гэта сказала, толькі тое, што Вы маеце mallocd павінны быць вызваленыя. Калі вы статычна абвясціць лік, INT х коскі, што жыве ў стэку, вы не тое хачу, каб вызваліць х. Так толькі тое, што вы mallocd павінны быць вызваленыя. І, нарэшце, ня бясплатна нешта ў два разы. Гэта можа прывесці да іншы дзіўная сітуацыя. Так што ўсё, што вы маеце mallocd павінен быць вызвалены. Толькі тое, што вы Таноса павінны быць вызваленыя. І не бясплатна нешта ў два разы. Такім чынам, давайце разгледзім прыклад тут што некаторыя дынамічна размяркоўваецца памяці можа выглядаць змяшанай у з некаторай статычнай памяці. Што можа здарыцца тут? Глядзіце, калі вы можаце прытрымлівацца ўздоўж і думаю, што адбудзецца, як мы ідзем усе гэтыя радкоў кода. Таму мы кажам, INT м. Што тут адбываецца? Ну гэта даволі проста. Я ствараю цэлае зменную м. Я пафарбаваць яго зялёным, таму што гэта колер што я выкарыстоўваю, калі я кажу аб цэлалікавых зменныя. Гэта скрынка. Гэта называецца м, і вы можаце магазін цэлыя ўнутры яго. Што рабіць, калі я тады сказаць INT зорцы? Ну, што гэта даволі падобныя. Я ствараю акно называецца. Ён здольны холдынгу Int зоркі, паказальнікі на цэлыя лікі. Так што я афарбоўкі гэта зялёны-иш, а таксама. Я ведаю, што ёсць нешта зрабіць з цэлым лікам, але гэта само па сабе не з'яўляецца цэлым лікам. Але гэта ў значнай ступені тая ж ідэя. Я стварыў акно. Абодва гэтыя правы у цяперашні час жывуць у стэку. Я даў ім імёны абодвух. INT зорка б роўная выдзялення памяці памер Int. Гэты можа быць крыху больш складана. Вазьміце другой і падумайце, што вы было б чакаць, каб гэта адбылося на гэтай дыяграме. INT зорка б роўная выдзялення памяці памер Int. Ну гэта не проста стварыць адну скрынку. Гэта на самай справе стварае дзве скрынкі. І гэта прывязвае, ён таксама ўстанаўлівае кропка ў адносінах. Мы выдзелена адзін блок памяці ў кучы. Звярніце ўвагу, што верхні правы скрыню значыць не ёсць імя. Мы mallocd яго. Яна існуе на кучы. Але Ь мае імя. Гэта пераменная паказальнік называецца б. Гэта жыве ў стэку. Так што гэта частка памяці што паказвае на іншы. б ўтрымлівае адрас гэтага блока памяці. Гэта не ёсць імя інакш. Але ён паказвае на яго. Таму калі мы гаворым INT зорка б роўная Памер Таноса ИНТ, што тут, што стрэлка, якая выскачыў на правая бок ёсць, што ўся рэч, Я ён з'явіцца зноў жа, тое, што адбываецца. Усё, што адбываецца ў што адна радок кода. Цяпер мы атрымаем трохі больш проста яшчэ раз. А роўна Ампэрсанд м. Памятаеш вам, што роўная Ампэрсанд м ёсць? Ну, гэта атрымлівае адрас M'S. Або, больш схематычна, а паказвае на м. А роўна б. ТАКІМ ЧЫНАМ, вось яшчэ адзін. А роўна б. Што адбудзецца дыяграме гэты час? Ну нагадаць, што Аператар прысвойвання працы шляхам прысваення значэння на Права на кошце злева. Такім чынам, замест паказваў м, А цяпер паказвае на тое ж месца, што б кропак. а, не паказваюць на B, A паказвае, дзе б балаў. Калі востры б, што б былі роўна Ампэрсанд б. Але замест гэтага роўная б толькі азначае, што б цяпер паказваючы на ​​той жа адрас, таму што ўнутры б толькі адрас. А цяпер ўнутры гэта той жа адрас. м роўная 10, верагодна, Найбольш простая справа мы зрабілі ў няшмат. Змесціце 10 у скрынцы. Зорка б роўная м плюс 2, нагадаем, з наш паказальнікі відэа, што зорка б азначае. Мы збіраемся разыменовывания б і пакласці некаторы значэнне ў гэтым месцы памяці. У гэтым выпадку 12. Таму, калі мы разыменовывать пункту Нагадаем, мы проста рухацца ўніз стрэлку. Або іншымі словамі, мы перайсці на гэты адрас памяці і мы маніпуляваць нейкім чынам. Мы ставім некаторы значэнне ў там. У гэтым выпадку зоркі У роўны т плюс 2 проста перайсці да зменнай, на якую паказвае б, перайсці да памяці, на якую паказвае б, і паклаў м плюс 2 там, 12. Цяпер я свабодна б. Што адбываецца, калі я вызваляю б? Памятаеце, што я сказаў, бясплатныя сродкі. Што я кажу, калі я вызваліцца б? Я зрабіў з ім працаваць, ці не так? Я па сутнасці адмовіцца ад памяці. Я даю яго назад у сістэму. Мне не трэба гэта больш з'яўляецца тое, што я кажу ім, ОК? Цяпер, калі я кажу зорцы роўная 11, верагодна, можна ўжо сказаць, што нешта дрэннае адбудзецца тут, прама? І на самай справе, калі я спрабаваў, што я, верагодна, будзе пакутаваць памылку сегментацыі. Таму што цяпер, хоць раней, што частка памяці было нешта, што я меў доступ да, у гэтай кропцы цяпер я доступу да памяці, што не з'яўляецца законным для мяне, каб атрымаць доступ. І, як мы, верагодна, Нагадаем, што, калі мы атрымліваем доступ да памяці што мы не павінны чапаць, гэта самая распаўсюджаная прычына з сегментацыі віна. І так мая праграма будзе катастрофа, калі я спрабаваў зрабіць гэта. Такім чынам, яшчэ раз, што гэта добрая ідэя, каб атрымаць добры практыка і добрыя звычкі ўкараніліся пры працы з Таноса і бясплатна, так што вы не пакутуеце сегментацыі памылкі, і што вы карыстаецеся Ваш вылучаецца дынамічна памяці адказна. Я Дуг Лойда гэта CS50.